最美情侣中文字幕电影,在线麻豆精品传媒,在线网站高清黄,久久黄色视频

歡迎光臨散文網(wǎng) 會(huì)員登陸 & 注冊(cè)

Qt+QtWebApp開(kāi)發(fā)筆記(四):http服務(wù)器使用Session和Cookie實(shí)現(xiàn)用戶(hù)密碼登錄和注銷(xiāo)功

2023-05-29 10:01 作者:紅胖子_AAA紅模仿  | 我要投稿

前言

??前面實(shí)現(xiàn)了基礎(chǔ)的跳轉(zhuǎn),那么動(dòng)態(tài)交互中登錄是常用功能。
??本篇實(shí)現(xiàn)一個(gè)動(dòng)態(tài)交互的簡(jiǎn)單登錄和注銷(xiāo)功能,在Qt中使用Session和Cookie技術(shù)。

Demo

??

下載地址

??鏈接:https://pan.baidu.com/s/1nkmsHgr-11Khe9k6Ntyf_g?pwd=1234

Html處理用戶(hù)輸入Session與Cookie

表單登錄submit

??Web應(yīng)用程序通常處理用戶(hù)輸入。將開(kāi)發(fā)一個(gè)登錄表單,看看進(jìn)展如何。
創(chuàng)建一個(gè)名為L(zhǎng)oginController的新類(lèi)。同樣,它是從HttpRequestHandl派生的

logincontroller.h:

#ifndef LOGINCONTROLLER_H#define LOGINCONTROLLER_H#include "httprequesthandler.h"using namespace stefanfrings;class LoginController : public HttpRequestHandler { ? ?Q_OBJECTpublic: ? ?LoginController(QObject* parent=0); ? ?void service(HttpRequest& request, HttpResponse& response);};#endif // LOGINCONTROLLER_H

logincontroller.cpp:

#include "logincontroller.h"LoginController::LoginController(QObject* parent) ? ?:HttpRequestHandler(parent) { ? ?// empty}void LoginController::service(HttpRequest &request, HttpResponse &response) { ? ?QByteArray username=request.getParameter("username"); ? ?QByteArray password=request.getParameter("password"); ? ?qDebug("username=%s",username.constData()); ? ?qDebug("password=%s",password.constData()); ? ?response.setHeader("Content-Type", "text/html; charset=UTF-8"); ? ?response.write("<html><body>"); ? ?if (username=="test" and password=="hello") { ? ? ? ?response.write("Yes, correct"); ? ?} ? ?else { ? ? ? ?response.write("<form method='POST' action='/login'>"); ? ? ? ?if (!username.isEmpty()) { ? ? ? ? ? ?response.write("No, that was wrong!<br><br>"); ? ? ? ?} ? ? ? ?response.write("Please log in:<br>"); ? ? ? ?response.write("Name: ?<input type='text' name='username'><br>"); ? ? ? ?response.write("Password: <input type='password' name='password'><br>"); ? ? ? ?response.write("<input type='submit'>"); ? ? ? ?response.write("</form"); ? ?} ? ?response.write("</body></html>",true);}

??(PS:html代表是提交表單)
??將這個(gè)新控制器添加到請(qǐng)求映射器中,修改requestmapper.h:

#ifndef REQUESTMAPPER_H#define REQUESTMAPPER_H#include "httprequesthandler.h"#include "helloworldcontroller.h"#include "listdatacontroller.h"#include "logincontroller.h"class RequestMapper : public HttpRequestHandler { ? ?Q_OBJECTpublic: ? ?RequestMapper(QObject* parent=0); ? ?void service(HttpRequest& request, HttpResponse& response);private: ? ?HelloWorldController helloWorldController; ? ?ListDataController listDataController; ? ?LoginController loginController;};#endif // REQUESTMAPPER_H

??修改requestmapper.cpp(切入了/login,調(diào)用loginController):

#include "requestmapper.h"RequestMapper::RequestMapper(QObject* parent) ? ?: HttpRequestHandler(parent) { ? ?// empty}void RequestMapper::service(HttpRequest& request, HttpResponse& response) { ? ?QByteArray path=request.getPath(); ? ?qDebug("RequestMapper: path=%s",path.data()); ? ?if (path=="/" || path=="/hello") { ? ? ? ?helloWorldController.service(request, response); ? ?} ? ?else if (path=="/list") { ? ? ? ?listDataController.service(request, response); ? ?} ? ?else if (path=="/login") { ? ? ? ?loginController.service(request, response); ? ?} ? ?else { ? ? ? ?response.setStatus(404,"Not found"); ? ? ? ?response.write("The URL is wrong, no such document."); ? ?} ? ?qDebug("RequestMapper: finished request");}

??運(yùn)行程序并打開(kāi)URLhttp://localhost:8080/login.將看到以下表格:

??


??嘗試使用錯(cuò)誤的名稱(chēng)和密碼登錄。然后瀏覽器顯示錯(cuò)誤消息“That was wrong”,并提示重試。如果輸入了正確的憑據(jù)(用戶(hù)名“test”和密碼“hello”),則會(huì)收到成功消息。

??HTML表單定義了兩個(gè)名為“username”和“password”的輸入字段??刂破魇褂胷equest.getParameter()來(lái)獲取這些值。

??當(dāng)參數(shù)為空或傳入的HTTP請(qǐng)求中沒(méi)有這樣的參數(shù)時(shí),Request.getParameter()?返回一個(gè)空的QByteArray。后一種情況發(fā)生在打開(kāi)URL時(shí)http://localhost:8080/login開(kāi)始只有當(dāng)用戶(hù)單擊提交按鈕時(shí),表單字段才會(huì)從web瀏覽器發(fā)送到web服務(wù)器。

??如果需要區(qū)分空字段和缺失字段,那么可以使用request.getParameterMap(),然后檢查所需參數(shù)是否在返回的映射中。

??作為表單的替代方案,參數(shù)也可以作為URL的一部分進(jìn)行傳輸。例如,也可以通過(guò)打開(kāi)URL登錄http://localhost:8080/login?username=test&password=hello.

??在URL中使用某些特殊字符時(shí),必須將其編碼為轉(zhuǎn)義序列。例如,如果用戶(hù)名是“Stefan Frings”,那么必須寫(xiě)http://localhost:8080/login?username=Stefan%20Frings&password=hello.HttpRequest類(lèi)會(huì)自動(dòng)將其解碼回原始形式“Stefan Frings”。

??如果需要將字符串編碼為URL格式,可以使用QUrl類(lèi)。

服務(wù)器本地會(huì)話session

??(PS:session和cookie是一起搭配使用的,cookie存在本地 session可以拿到cookie來(lái)判斷是否登錄了,等一些已有的狀態(tài))
??下一個(gè)合乎邏輯的步驟是處理會(huì)話數(shù)據(jù)。這意味著,將當(dāng)前用戶(hù)的數(shù)據(jù)保存在某個(gè)地方,并在后續(xù)請(qǐng)求中使用這些數(shù)據(jù)。將存儲(chǔ)的第一個(gè)數(shù)據(jù)是用戶(hù)的姓名和登錄時(shí)間。
??QtWebApp使用隱藏的cookie來(lái)識(shí)別用戶(hù)。
??必須在控制會(huì)話存儲(chǔ)類(lèi)的配置文件webapp1.ini中添加一個(gè)新的部分:

[sessions]expirationTime=3600000cookieName=sessionid;cookieDomain=mydomain.com cookiePath=/cookieComment=Identifies the user

??過(guò)期時(shí)間定義從內(nèi)存中刪除未使用的會(huì)話后的毫秒數(shù)。當(dāng)用戶(hù)在該時(shí)間之后返回時(shí),他的會(huì)話將丟失,因此他必須再次登錄。

  • expirationTime:保存時(shí)間,實(shí)際上從后面的cookie截圖可以看到是3600000ms,則是3600秒一小時(shí)的時(shí)間過(guò)期,這個(gè)保存后的默認(rèn)過(guò)期時(shí)間。
    ??

  • sessionid:cookie名稱(chēng)可以是任意名稱(chēng),但通常使用名稱(chēng)“sessionid”。有些負(fù)載均衡器依賴(lài)于這個(gè)名稱(chēng),所以除非有充分的理由,否則不應(yīng)該更改它。

  • cookieDomain:每個(gè)cookie總是綁定到一個(gè)域。由google.com生成的cookie只發(fā)送到該域上的服務(wù)器。如果將cookieDomain參數(shù)留空或?qū)⑵渥⑨尩?,則該參數(shù)將由web瀏覽器自動(dòng)設(shè)置??梢灾付硪粋€(gè)域名,但不知道男人為什么要這么做。所以,除非知道自己在做什么,否則就把它空著。

  • cookiePath:cookie路徑可用于將cookie限制在的域的一部分。如果將cookiePath更改為/my/very/cool/online/shop,則瀏覽器將僅針對(duì)以該路徑開(kāi)頭的頁(yè)面將cookie發(fā)送到的服務(wù)器。默認(rèn)值為“/”,這意味著cookie對(duì)域中的所有網(wǎng)站都有效。

  • cookieComment:cookieComment是一些網(wǎng)絡(luò)瀏覽器在cookie管理屏幕中顯示的文本。
    ??需要HttpSessionStore類(lèi)的一個(gè)實(shí)例,整個(gè)程序都可以訪問(wèn)該實(shí)例,因此可以在全局空間中訪問(wèn)。因此,創(chuàng)建了兩個(gè)新文件,第一個(gè)是global.h:

#ifndef GLOBAL_H#define GLOBAL_H#include "httpsessionstore.h"using namespace stefanfrings;extern HttpSessionStore* sessionStore;#endif // GLOBAL_H

??global.cpp:

#include "global.h"HttpSessionStore* sessionStore;

??現(xiàn)在有了一個(gè)名為“sessionStore”的全局靜態(tài)指針,整個(gè)程序可以通過(guò)包含global.h文件來(lái)訪問(wèn)該指針。讓加載新的配置設(shè)置并初始化sessionStore。
??main.cpp中的更改:

#include "global.h"int main(int argc, char *argv[]){ ? ?QCoreApplication app(argc, argv); ? ?QString configFileName=searchConfigFile(); ? ?// Session store ? ?QSettings* sessionSettings=new QSettings(configFileName,QSettings::IniFormat,&app); ? ?sessionSettings->beginGroup("sessions"); ? ?sessionStore=new HttpSessionStore(sessionSettings,&app); ? ?// HTTP server ? ?QSettings* listenerSettings=new QSettings(configFileName,QSettings::IniFormat,&app); ? ?listenerSettings->beginGroup("listener"); ? ?new HttpListener(listenerSettings,new RequestMapper(&app),&app); ? ?return app.exec();}

??請(qǐng)注意,main.cpp現(xiàn)在加載配置文件兩次。sessionSettings對(duì)象選擇“sessions”部分,而listenerSettings選擇“l(fā)istener”部分。對(duì)于每個(gè)部分,需要一個(gè)單獨(dú)的QSettings實(shí)例,否則這些部分可能會(huì)混淆。
??既然已經(jīng)為會(huì)話數(shù)據(jù)創(chuàng)建了一個(gè)存儲(chǔ),就可以開(kāi)始使用它了。添加到logincontroller.cpp:

#include <QTime>#include "logincontroller.h"#include "global.h"LoginController::LoginController(QObject* parent) ? ?:HttpRequestHandler(parent) { ? ?// empty}void LoginController::service(HttpRequest &request, HttpResponse &response) { ? ?HttpSession session=sessionStore->getSession(request,response,true); ? ?QByteArray username=request.getParameter("username"); ? ?QByteArray password=request.getParameter("password"); ? ?qDebug("username=%s",username.constData()); ? ?qDebug("password=%s",password.constData()); ? ?response.setHeader("Content-Type", "text/html; charset=UTF-8"); ? ?response.write("<html><body>"); ? ?if (session.contains("username")) { ? ? ? ?QByteArray username=session.get("username").toByteArray(); ? ? ? ?QTime logintime=session.get("logintime").toTime(); ? ? ? ?response.write("You are already logged in.<br>"); ? ? ? ?response.write("Your name is: "+username+"<br>"); ? ? ? ?response.write("You logged in at: "+logintime.toString("HH:mm:ss")+"<br>"); ? ?} ? ?else { ? ? ? ?if (username=="test" and password=="hello") { ? ? ? ? ? ?response.write("Yes, correct"); ? ? ? ? ? ?session.set("username",username); ? ? ? ? ? ?session.set("logintime",QTime::currentTime()); ? ? ? ?} ? ? ? ?else { ? ? ? ? ? ?response.write("<form method='POST' action='/login'>"); ? ? ? ? ? ?if (!username.isEmpty()) { ? ? ? ? ? ? ? ?response.write("No, that was wrong!<br><br>"); ? ? ? ? ? ?} ? ? ? ? ? ?response.write("Please log in:<br>"); ? ? ? ? ? ?response.write("Name: ?<input type='text' name='username'><br>"); ? ? ? ? ? ?response.write("Password: <input type='password' name='password'><br>"); ? ? ? ? ? ?response.write("<input type='submit'>"); ? ? ? ? ? ?response.write("</form"); ? ? ? ?} ? ?} ? ?response.write("</body></html>",true);}

??在這里,重要的是在第一次調(diào)用response.write()之前調(diào)用sessionStore->getSession(),因?yàn)樗鼊?chuàng)建或刷新會(huì)話cookie,從技術(shù)上講,它是一個(gè)HTTP頭。并且所有HTTP標(biāo)頭都必須在HTML文檔之前發(fā)送。
??通過(guò)打開(kāi)來(lái)運(yùn)行和測(cè)試程序http://localhost:8080/login.
??


??現(xiàn)在查看web服務(wù)器的控制臺(tái)窗口時(shí),看到一個(gè)cookie和一個(gè)會(huì)話是用一個(gè)唯一的id創(chuàng)建的,這個(gè)id是一個(gè)長(zhǎng)的隨機(jī)十六進(jìn)制數(shù)。
??從Chromium瀏覽器中截取了以下截圖,可以在其中看到cookie:
??


??用戶(hù)會(huì)話最初為空。它只是存在,并且有一個(gè)唯一的id號(hào)。沒(méi)有別的。輸入用戶(hù)名“test”和密碼“hello”。然后會(huì)得到預(yù)期的確認(rèn)。
??


??在確認(rèn)登錄成功的同時(shí),服務(wù)器將用戶(hù)名和登錄時(shí)間輸入到用戶(hù)會(huì)話中??梢詫⑷魏螌?duì)象放入QVariant支持的會(huì)話中。當(dāng)將一個(gè)對(duì)象放入會(huì)話時(shí),會(huì)給它一個(gè)符號(hào)名稱(chēng),以便以后訪問(wèn)。
??現(xiàn)在再次打開(kāi)URLhttp://localhost:8080/login.然后會(huì)看到所有這些工作的結(jié)果:
??


??因此,在成功驗(yàn)證用戶(hù)名和密碼后,服務(wù)器使用會(huì)話來(lái)記住該用戶(hù)的數(shù)據(jù)。
??會(huì)話存儲(chǔ)保存在內(nèi)存中。重新啟動(dòng)web服務(wù)器時(shí),會(huì)話存儲(chǔ)中的所有數(shù)據(jù)都會(huì)丟失。因此,只將其用于一些臨時(shí)數(shù)據(jù)。持久性數(shù)據(jù)屬于一個(gè)數(shù)據(jù)庫(kù)。

用戶(hù)本地終端的存儲(chǔ)cookies

??作為會(huì)話存儲(chǔ)的替代方案,也可以在cookie中存儲(chǔ)少量數(shù)據(jù)。Cookie存儲(chǔ)在web瀏覽器的客戶(hù)端,而不是服務(wù)器端。Cookie只能存儲(chǔ)8位的文本,并且只能保證4 KB的容量。此外,每個(gè)域的cookie數(shù)量是有限的,因此請(qǐng)保留使用它們。
??為了嘗試這一點(diǎn),添加一個(gè)名為CookieTestController的新控制器類(lèi),并將其綁定到路徑“/cookie”。

cookietestcontroller.cpp:

#include "cookietestcontroller.h" CookieTestController::CookieTestController(QObject* parent) ? ? : HttpRequestHandler(parent) { ? ? // empty } void CookieTestController::service(HttpRequest &request, HttpResponse &response) { ? ? QByteArray cookie=request.getCookie("testcookie"); ? ? if (!cookie.isEmpty()) { ? ? ? ? response.write("Found cookie with value: "+cookie,true); ? ? } ? ? else { ? ? ? ? HttpCookie cookie("testcookie","123456789",60); ? ? ? ? response.setCookie(cookie); ? ? ? ? response.write("A new cookie has been created.",true); ? ? } }

??cookie的名稱(chēng)為“testcookie”,其值為“123456789”。60是以秒為單位的有效時(shí)間。?此cookie在創(chuàng)建一分鐘后過(guò)期。這段短暫的時(shí)間來(lái)看看cookie過(guò)期后會(huì)發(fā)生什么。通常會(huì)使用更大的時(shí)間,可能是幾天。
??Request.getCookie()只返回cookie的值,而不是整個(gè)HttpCookie對(duì)象。這是出于性能原因。
??運(yùn)行程序并打開(kāi)http://localhost:8080/cookie.
??

??然后再次加載同一頁(yè)面,將看到服務(wù)器正確接收到cookie:
??

??Cookie存儲(chǔ)在網(wǎng)絡(luò)瀏覽器中,并隨每個(gè)HTTP請(qǐng)求一起發(fā)送到網(wǎng)絡(luò)服務(wù)器。除了會(huì)話數(shù)據(jù)之外,如果重新啟動(dòng)服務(wù)器,cookie不會(huì)丟失,因?yàn)閏ookie存儲(chǔ)在客戶(hù)端。
??Chromium瀏覽器的屏幕截圖:
??

??在這里,可以看到會(huì)話cookie仍然存在?,F(xiàn)在有兩個(gè)本地主機(jī)域的cookie。
??如果等待兩分鐘,然后再次加載http://localhost:8080/cookie將看到測(cè)試cookie已過(guò)期。服務(wù)器會(huì)創(chuàng)建一個(gè)新的。
??如果想防止cookie在用戶(hù)處于活動(dòng)狀態(tài)時(shí)過(guò)期,那么必須在每次請(qǐng)求時(shí)重新創(chuàng)建cookie。然后,瀏覽器會(huì)為每個(gè)請(qǐng)求計(jì)算一個(gè)新的截止日期。

Demo增量:實(shí)戰(zhàn)用戶(hù)登錄

步驟一:準(zhǔn)備代碼模板

??準(zhǔn)備之前的demo v1.2.0模板:
??

步驟二:新增登錄入口處理LoginRequestHandler

??

??修改一下:
??

??

步驟三:將登錄界面的html的添加進(jìn)登錄入口

??

void LoginRequestHandler::service(HttpRequest &request, HttpResponse &response) { ? ? QString str; ? ? QString path = request.getPath(); ? ? LOG << path; ? ? str = "<!DOCTYPE html>" ? ? ? ? ? "<html lang=\"en\">" ? ? ? ? ? "<head>" ? ? ? ? ? "<meta charset=\"UTF-8\">" ? ? ? ? ? "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">" ? ? ? ? ? "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">" ? ? ? ? ? "<title>長(zhǎng)沙紅胖子Qt</title>" ? ? ? ? ? "</head>" ? ? ? ? ? "<body>" ? ? ? ? ? " ? ?<a href=\"javascript:history.back(-1);\">返回上一頁(yè)</a>" ? ? ? ? ? " ? ?<form method='POST' action='/login'>" ? ? ? ? ? " ? ? ? ?<p>Please login</p>" ? ? ? ? ? " ? ? ? ?<p>Name: <input type='text' name='username'></p>" ? ? ? ? ? " ? ? ? ?<p>Password: <input type='password' name='password'></p>" ? ? ? ? ? " ? ? ? ?<p><input type='submit'></p>" ? ? ? ? ? " ? ?</form>" ? ? ? ? ? "</body>"; ? ? // 返回文本(需要在瀏覽器上看,所以將Qt內(nèi)部編碼都轉(zhuǎn)成GBK輸出即可,不管他本身是哪個(gè)編碼) // ? ?QByteArray byteArray = _pTextCodec->fromUnicode(str); ? ? QByteArray byteArray = str.toUtf8(); ? ? response.write(byteArray); }

步驟四:在原來(lái)Index上新增一個(gè)連接地址跳轉(zhuǎn)登錄

??


??

??這個(gè)時(shí)候是可以跳轉(zhuǎn)了。
??


??此時(shí),登錄打印:
??


??可以,其路徑提交也是觸發(fā)了一次進(jìn)入login的service,這時(shí)候就需要通過(guò)Session的變量來(lái)判斷是第一次進(jìn)入還是提交登錄。

步驟五:添加sessionStore頭文件

??SessionStore頭文件在httpserver模塊中。
??

步驟六:添加唯一實(shí)例類(lèi)sessionStore,封裝session存儲(chǔ)類(lèi)

??


??


??

步驟七:添加配置文件

[sessions] expirationTime=3600000 cookieName=sessionid ;cookieDomain=mydomain.com cookiePath=/ cookieComment=Identifies the user

??

步驟八:添加session加載配置代碼

??


??

步驟九:通過(guò)session判斷

??在沒(méi)有session之前是可以獲取表單提交的參數(shù):
??

??添加session判斷后:

void LoginRequestHandler::service(HttpRequest &request, HttpResponse &response) { ? ? QString str; ? ? QString path = request.getPath(); ? ? LOG << path; ? ? // 這里獲取到的param是直接獲取的 ? ? QString userName = request.getParameter("username"); ? ? QString password = request.getParameter("password"); ? ? LOG << userName << password; ? ? // 獲取session(單例模式封裝后的全局獲取) ? ? HttpSession httpSession = ? ? ? ? ? ? HttpSessionStoreManager::getInstance()->getHttpSessionStore()->getSession(request,response,true); ? ? // 先判斷是否session能獲取到 ? ? if(!httpSession.contains("username")) ? ? { ? ? ? ? // 這里沒(méi)有cookie,提交登錄則是可以保存本地cookie ? ? ? ? if(userName == "root" && password == "root123456") ? ? ? ? { ? ? ? ? ? ? httpSession.set("username" , userName); ? ? ? ? ? ? httpSession.set("logintime", QTime::currentTime()); ? ? ? ? ? ? httpSession.set("timeout" ?, 60); ? ? ? ? ? ? QString username = httpSession.get("username").toString(); ? ? ? ? ? ? QTime logintime = httpSession.get("logintime").toTime(); ? ? ? ? ? ? int timeout = httpSession.get("timeout").toInt(); ? ? ? ? ? ? str = QString("<!DOCTYPE html>" ? ? ? ? ? ? ? ? ? ? ? ? ? "<html lang=\"en\">" ? ? ? ? ? ? ? ? ? ? ? ? ? "<head>" ? ? ? ? ? ? ? ? ? ? ? ? ? "<meta charset=\"UTF-8\">" ? ? ? ? ? ? ? ? ? ? ? ? ? "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">" ? ? ? ? ? ? ? ? ? ? ? ? ? "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">" ? ? ? ? ? ? ? ? ? ? ? ? ? "<title>長(zhǎng)沙紅胖子Qt</title>" ? ? ? ? ? ? ? ? ? ? ? ? ? "</head>" ? ? ? ? ? ? ? ? ? ? ? ? ? "<body>" ? ? ? ? ? ? ? ? ? ? ? ? ? " ? ?<a href=\"javascript:history.back(-1);\">注銷(xiāo)登錄</a>" ? ? ? ? ? ? ? ? ? ? ? ? ? " ? ?<p>登錄賬戶(hù):%1</p>" ? ? ? ? ? ? ? ? ? ? ? ? ? " ? ?<p>登錄時(shí)間:%2</p>" ? ? ? ? ? ? ? ? ? ? ? ? ? " ? ?<p>超時(shí)時(shí)間:%3</p>" ? ? ? ? ? ? ? ? ? ? ? ? ? "</body>") ? ? ? ? ? ? ? ? ? ? .arg(username) ? ? ? ? ? ? ? ? ? ? .arg(logintime.toString("hh:mm:ss:zzz")) ? ? ? ? ? ? ? ? ? ? .arg(timeout); ? ? ? ? }else{ ? ? ? ? ? ? str = "<!DOCTYPE html>" ? ? ? ? ? ? ? ? ? "<html lang=\"en\">" ? ? ? ? ? ? ? ? ? "<head>" ? ? ? ? ? ? ? ? ? "<meta charset=\"UTF-8\">" ? ? ? ? ? ? ? ? ? "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">" ? ? ? ? ? ? ? ? ? "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">" ? ? ? ? ? ? ? ? ? "<title>長(zhǎng)沙紅胖子Qt</title>" ? ? ? ? ? ? ? ? ? "</head>" ? ? ? ? ? ? ? ? ? "<body>" ? ? ? ? ? ? ? ? ? " ? ?<a href=\"javascript:history.back(-1);\">返回上一頁(yè)</a>" ? ? ? ? ? ? ? ? ? " ? ?<form method='POST' action='/login'>" ? ? ? ? ? ? ? ? ? " ? ? ? ?<p>Please login</p>" ? ? ? ? ? ? ? ? ? " ? ? ? ?<p>Name: <input type='text' name='username'></p>" ? ? ? ? ? ? ? ? ? " ? ? ? ?<p>Password: <input type='password' name='password'></p>" ? ? ? ? ? ? ? ? ? " ? ? ? ?<p><input type='submit'></p>" ? ? ? ? ? ? ? ? ? " ? ?</form>" ? ? ? ? ? ? ? ? "</body>"; ? ? ? ? } ? ? }else { ? ? ? ? // 之前已經(jīng)登錄過(guò)了 ? ? ? ? QString username = httpSession.get("username").toString(); ? ? ? ? QTime logintime = httpSession.get("logintime").toTime(); ? ? ? ? int timeout = httpSession.get("timeout").toInt(); ? ? ? ? str = QString("<!DOCTYPE html>" ? ? ? ? ? ? ? ? ? ? ? "<html lang=\"en\">" ? ? ? ? ? ? ? ? ? ? ? "<head>" ? ? ? ? ? ? ? ? ? ? ? "<meta charset=\"UTF-8\">" ? ? ? ? ? ? ? ? ? ? ? "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">" ? ? ? ? ? ? ? ? ? ? ? "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">" ? ? ? ? ? ? ? ? ? ? ? "<title>長(zhǎng)沙紅胖子Qt</title>" ? ? ? ? ? ? ? ? ? ? ? "</head>" ? ? ? ? ? ? ? ? ? ? ? "<body>" ? ? ? ? ? ? ? ? ? ? ? " ? ?<a href=\"javascript:history.back(-1);\">注銷(xiāo)登錄</a>" ? ? ? ? ? ? ? ? ? ? ? " ? ?<p>登錄賬戶(hù):%1</p>" ? ? ? ? ? ? ? ? ? ? ? " ? ?<p>登錄時(shí)間:%2</p>" ? ? ? ? ? ? ? ? ? ? ? " ? ?<p>超時(shí)時(shí)間:%3</p>" ? ? ? ? ? ? ? ? ? ? ? "</body>") ? ? ? ? ? ? ? ? .arg(username) ? ? ? ? ? ? ? ? .arg(logintime.toString("hh:mm:ss:zzz")) ? ? ? ? ? ? ? ? .arg(timeout); ? ? } ? ? // 返回文本(需要在瀏覽器上看,所以將Qt內(nèi)部編碼都轉(zhuǎn)成GBK輸出即可,不管他本身是哪個(gè)編碼) // ? ?QByteArray byteArray = _pTextCodec->fromUnicode(str); ? ? QByteArray byteArray = str.toUtf8(); ? ? response.write(byteArray); }

??查看session
??

步驟十:添加一個(gè)“注銷(xiāo)登錄”

??

// 注銷(xiāo),清空session if(path == "/login/out") { ? ? HttpSession httpSession = ? ? ? ? ? ? HttpSessionStoreManager::getInstance()->getHttpSessionStore()->getSession(request,response,true); ? ? HttpSessionStoreManager::getInstance()->getHttpSessionStore()->removeSession(httpSession); }

Demo源碼

LoginRequestHandler.h

#ifndef LOGINREQUESTHANDLER_H #define LOGINREQUESTHANDLER_H #include "httprequesthandler.h" #include "HelloWorldRequestHandler.h" #include "ListRequestHandler.h" using namespace stefanfrings; class LoginRequestHandler : public HttpRequestHandler { public: ? ? LoginRequestHandler(QObject *parent = 0); public: ? ? void service(HttpRequest& request, HttpResponse& response); private: ? ? QTextCodec *_pTextCodec; private: }; #endif // LoginRequestHandler_H

LoginRequestHandler.cpp

#include "LoginRequestHandler.h" #include "ListRequestHandler.h" #include "HttpSessionStoreManager.h" #include <QTextCodec> #include <QDebug> #include <QDateTime> //#define LOG qDebug()<<__FILE__<<__LINE__ //#define LOG qDebug()<<__FILE__<<__LINE__<<__FUNCTION__ //#define LOG qDebug()<<__FILE__<<__LINE__<<QThread()::currentThread() //#define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd") #define LOG qDebug()<<__FILE__<<__LINE__<<QDateTime::currentDateTime().toString("yyyy-MM-dd hh:mm:ss:zzz") using namespace stefanfrings; LoginRequestHandler::LoginRequestHandler(QObject *parent) ? ? : HttpRequestHandler(parent) { ? ? // 返回文本(需要在瀏覽器上看,所以將Qt內(nèi)部編碼都轉(zhuǎn)成GBK輸出即可,不管他本身是哪個(gè)編碼) ? ? // WINDOWS: GBK ?GB2312 ? ? // LINUX ?: urf-8 // ? ?_pTextCodec = QTextCodec::codecForName("utf-8"); ? ? _pTextCodec = QTextCodec::codecForName("GBK"); } void LoginRequestHandler::service(HttpRequest &request, HttpResponse &response) { ? ? QString str; ? ? QString path = request.getPath(); ? ? LOG << path; ? ? // 這里獲取到的param是直接獲取的 ? ? QString userName = request.getParameter("username"); ? ? QString password = request.getParameter("password"); ? ? LOG << userName << password; ? ? // 注銷(xiāo),清空session ? ? if(path == "/login/out") ? ? { ? ? ? ? HttpSession httpSession = ? ? ? ? ? ? ? ? HttpSessionStoreManager::getInstance()->getHttpSessionStore()->getSession(request,response,true); ? ? ? ? HttpSessionStoreManager::getInstance()->getHttpSessionStore()->removeSession(httpSession); ? ? } ? ? // 獲取session(單例模式封裝后的全局獲取) ? ? HttpSession httpSession = ? ? ? ? ? ? HttpSessionStoreManager::getInstance()->getHttpSessionStore()->getSession(request,response,true); ? ? // 先判斷是否session能獲取到 ? ? if(!httpSession.contains("username")) ? ? { ? ? ? ? // 這里沒(méi)有cookie,提交登錄則是可以保存本地cookie ? ? ? ? if(userName == "root" && password == "root123456") ? ? ? ? { ? ? ? ? ? ? httpSession.set("username" , userName); ? ? ? ? ? ? httpSession.set("logindatetime", QDateTime::currentDateTime()); ? ? ? ? ? ? httpSession.set("timeout" ?, 60); ? ? ? ? ? ? QString username = httpSession.get("username").toString(); ? ? ? ? ? ? QDateTime logindatetime = httpSession.get("logindatetime").toDateTime(); ? ? ? ? ? ? int timeout = httpSession.get("timeout").toInt(); ? ? ? ? ? ? str = QString("<!DOCTYPE html>" ? ? ? ? ? ? ? ? ? ? ? ? ? "<html lang=\"en\">" ? ? ? ? ? ? ? ? ? ? ? ? ? "<head>" ? ? ? ? ? ? ? ? ? ? ? ? ? "<meta charset=\"UTF-8\">" ? ? ? ? ? ? ? ? ? ? ? ? ? "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">" ? ? ? ? ? ? ? ? ? ? ? ? ? "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">" ? ? ? ? ? ? ? ? ? ? ? ? ? "<title>長(zhǎng)沙紅胖子Qt</title>" ? ? ? ? ? ? ? ? ? ? ? ? ? "</head>" ? ? ? ? ? ? ? ? ? ? ? ? ? "<body>" ? ? ? ? ? ? ? ? ? ? ? ? ? " ? ?<a href=\"/login/out\"><input value='注銷(xiāo)' type='reset'></a>" ? ? ? ? ? ? ? ? ? ? ? ? ? " ? ?<p>登錄賬戶(hù):%1</p>" ? ? ? ? ? ? ? ? ? ? ? ? ? " ? ?<p>登錄時(shí)間:%2</p>" ? ? ? ? ? ? ? ? ? ? ? ? ? " ? ?<p>超時(shí)時(shí)間:%3</p>" ? ? ? ? ? ? ? ? ? ? ? ? ? "</body>") ? ? ? ? ? ? ? ? ? ? .arg(username) ? ? ? ? ? ? ? ? ? ? .arg(logindatetime.toString("yyyy-MM-dd hh:mm:ss:zzz")) ? ? ? ? ? ? ? ? ? ? .arg(timeout); ? ? ? ? }else{ ? ? ? ? ? ? str = "<!DOCTYPE html>" ? ? ? ? ? ? ? ? ? "<html lang=\"en\">" ? ? ? ? ? ? ? ? ? "<head>" ? ? ? ? ? ? ? ? ? "<meta charset=\"UTF-8\">" ? ? ? ? ? ? ? ? ? "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">" ? ? ? ? ? ? ? ? ? "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">" ? ? ? ? ? ? ? ? ? "<title>長(zhǎng)沙紅胖子Qt</title>" ? ? ? ? ? ? ? ? ? "</head>" ? ? ? ? ? ? ? ? ? "<body>" ? ? ? ? ? ? ? ? ? " ? ?<a href=\"javascript:history.back(-1);\">返回上一頁(yè)</a>" ? ? ? ? ? ? ? ? ? " ? ?<form method='POST' action='/login'>" ? ? ? ? ? ? ? ? ? " ? ? ? ?<p>Please login</p>" ? ? ? ? ? ? ? ? ? " ? ? ? ?<p>Name: <input type='text' name='username'></p>" ? ? ? ? ? ? ? ? ? " ? ? ? ?<p>Password: <input type='password' name='password'></p>" ? ? ? ? ? ? ? ? ? " ? ? ? ?<p><input type='submit'></p>" ? ? ? ? ? ? ? ? ? " ? ?</form>" ? ? ? ? ? ? ? ? "</body>"; ? ? ? ? } ? ? }else { ? ? ? ? // 之前已經(jīng)登錄過(guò)了 ? ? ? ? QString username = httpSession.get("username").toString(); ? ? ? ? QDateTime logindatetime = httpSession.get("logindatetime").toDateTime(); ? ? ? ? int timeout = httpSession.get("timeout").toInt(); ? ? ? ? str = QString("<!DOCTYPE html>" ? ? ? ? ? ? ? ? ? ? ? "<html lang=\"en\">" ? ? ? ? ? ? ? ? ? ? ? "<head>" ? ? ? ? ? ? ? ? ? ? ? "<meta charset=\"UTF-8\">" ? ? ? ? ? ? ? ? ? ? ? "<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">" ? ? ? ? ? ? ? ? ? ? ? "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">" ? ? ? ? ? ? ? ? ? ? ? "<title>長(zhǎng)沙紅胖子Qt</title>" ? ? ? ? ? ? ? ? ? ? ? "</head>" ? ? ? ? ? ? ? ? ? ? ? "<body>" ? ? ? ? ? ? ? ? ? ? ? " ? ?<a href=\"/login/out\"><input value='注銷(xiāo)' type='reset'></a>" ? ? ? ? ? ? ? ? ? ? ? " ? ?<p>登錄賬戶(hù):%1</p>" ? ? ? ? ? ? ? ? ? ? ? " ? ?<p>登錄時(shí)間:%2</p>" ? ? ? ? ? ? ? ? ? ? ? " ? ?<p>超時(shí)時(shí)間:%3</p>" ? ? ? ? ? ? ? ? ? ? ? "</body>") ? ? ? ? ? ? ? ? .arg(username) ? ? ? ? ? ? ? ? .arg(logindatetime.toString("yyyy-MM-dd hh:mm:ss:zzz")) ? ? ? ? ? ? ? ? .arg(timeout); ? ? } ? ? // 返回文本(需要在瀏覽器上看,所以將Qt內(nèi)部編碼都轉(zhuǎn)成GBK輸出即可,不管他本身是哪個(gè)編碼) // ? ?QByteArray byteArray = _pTextCodec->fromUnicode(str); ? ? QByteArray byteArray = str.toUtf8(); ? ? response.write(byteArray); }

工程模板v1.3.0

??


Qt+QtWebApp開(kāi)發(fā)筆記(四):http服務(wù)器使用Session和Cookie實(shí)現(xiàn)用戶(hù)密碼登錄和注銷(xiāo)功的評(píng)論 (共 條)

分享到微博請(qǐng)遵守國(guó)家法律
竹北市| 德钦县| 广饶县| 南江县| 高陵县| 宾川县| 吴江市| 肇东市| 迁安市| 荣成市| 天水市| 彰化市| 文化| 得荣县| 章丘市| 正宁县| 金山区| 渭源县| 巩义市| 孝昌县| 涟源市| 旅游| 会宁县| 石家庄市| 桃源县| 瓦房店市| 大理市| 邵武市| 台南市| 宾阳县| 贵州省| 新昌县| 文水县| 东城区| 青海省| 淳安县| 阜新| 邯郸县| 博客| 林周县| 修文县|