程序的背景(以防有帮助):
我正在尝试制作一个简单的包装器,以绕过"web应用程序“,使它们具有传统应用程序所带来的一些外观/感觉+隔离。我知道使用web技术可以使跨平台的开发变得更加容易(尤其是在UI方面),但我不喜欢它已经成为许多开发团队的一种捕捉所有解决方案的方式。我不想在我的浏览器里运行软件。
浏览器很重,支持与应用程序所做的功能无关的广泛功能,而将程序功能完全放在浏览器选项卡中可能会导致笨重的用户体验(我正在关注linux的Bittorrent Sync )。相反,我宁愿使用一个精简的浏览器,它要轻得多,并且运行在它自己的独立空间中,而不是在浏览器生态系统中运行。
附加功能可以很容易地附加,以提供更流畅的用户体验(例如,如果用户不启动程序并试图通过浏览器连接到它,他们将获得HTTP错误代码)。在这个单独的包装器中,程序可以读取错误代码本身,并显示一些预加载的html,从而提供一个特定于程序的更有用的错误)。
为此,我尝试使用Qt创建一个浏览器,它只是一个web呈现器、http通信器、cookie支持和一些基本的管理功能(运行程序的快捷方式,而不是依赖命令行)。
问题:
检查“留置签到”框没有任何作用。我非常肯定,在works中签名的方式是服务器为浏览器生成一个身份验证,以便将其存储为cookie。
当我登录到我的google帐户时,我可以看到几个在登录后创建的cookie似乎就是这样做的。我可以访问我的gmail、日历等,当我退出时,非会话cookie将存储到磁盘上。
当我启动程序备份时,它们将从磁盘加载,并出现在每个请求中,但我没有被登录到帐户中,登录链接是可见的。如果我不再登录,当程序存在时,旧的cookie不会再次存储到磁盘中。
以下是cookies的一些调试输出,当我登录时关闭程序(cookies保存到磁盘),然后重新启动程序(从磁盘加载),然后关闭它而不再次登录(保存了cookie):
SAVING COOKIES
GAPS=1:8-XXXXX; secure; HttpOnly; expires=Sat, 01-Jul-2017 17:34:10 GMT; domain=accounts.google.com; path=/
NID=XXXXX; HttpOnly; expires=Fri, 01-Jan-2016 17:34:10 GMT; domain=.google.com; path=/
SID=XXXXX; expires=Sat, 01-Jul-2017 17:34:10 GMT; domain=.google.com; path=/
LSID=XXXXX; secure; HttpOnly; expires=Sat, 01-Jul-2017 17:34:10 GMT; domain=accounts.google.com; path=/
HSID=XXXXX; HttpOnly; expires=Sat, 01-Jul-2017 17:34:10 GMT; domain=.google.com; path=/
SSID=XXXXX; secure; HttpOnly; expires=Sat, 01-Jul-2017 17:34:10 GMT; domain=.google.com; path=/
APISID=XXXXX; expires=Sat, 01-Jul-2017 17:34:10 GMT; domain=.google.com; path=/
SAPISID=XXXXX; secure; expires=Sat, 01-Jul-2017 17:34:10 GMT; domain=.google.com; path=/
ACCOUNT_CHOOSER=XXXXX; secure; HttpOnly; expires=Sat, 01-Jul-2017 17:34:10 GMT; domain=accounts.google.com; path=/
PREF=ID=1111111111111111:FF=0:LD=en:TM=XXXXX:LM=XXXXX:V=1:S=XXXXX_rr5; expires=Sat, 01-Jul-2017 17:34:10 GMT; domain=.google.com; path=/
OGPC=5-2:; expires=Sat, 01-Aug-2015 17:34:10 GMT; domain=.google.com; path=/
OTZ=XXXXX; secure; expires=Sat, 01-Aug-2015 17:34:15 GMT; domain=plus.google.com; path=/
build-WebView-Desktop-Debug/WebView exited with code 0
LOADING COOKIES
GAPS=1:8-XXXXX; secure; HttpOnly; expires=Sat, 01-Jul-2017 17:34:10 GMT; domain=accounts.google.com; path=/
NID=XXXXX; HttpOnly; expires=Fri, 01-Jan-2016 17:34:10 GMT; domain=.google.com; path=/
SID=XXXXX; expires=Sat, 01-Jul-2017 17:34:10 GMT; domain=.google.com; path=/
LSID=XXXXX; secure; HttpOnly; expires=Sat, 01-Jul-2017 17:34:10 GMT; domain=accounts.google.com; path=/
HSID=XXXXX; HttpOnly; expires=Sat, 01-Jul-2017 17:34:10 GMT; domain=.google.com; path=/
SSID=XXXXX; secure; HttpOnly; expires=Sat, 01-Jul-2017 17:34:10 GMT; domain=.google.com; path=/
APISID=XXXXX; expires=Sat, 01-Jul-2017 17:34:10 GMT; domain=.google.com; path=/
SAPISID=XXXXX; secure; expires=Sat, 01-Jul-2017 17:34:10 GMT; domain=.google.com; path=/
ACCOUNT_CHOOSER=XXXXX; secure; HttpOnly; expires=Sat, 01-Jul-2017 17:34:10 GMT; domain=accounts.google.com; path=/
PREF=ID=1111111111111111:FF=0:LD=en:TM=XXXXX:LM=XXXXX:V=1:S=XXXXX_rr5; expires=Sat, 01-Jul-2017 17:34:10 GMT; domain=.google.com; path=/
OGPC=5-2:; expires=Sat, 01-Aug-2015 17:34:10 GMT; domain=.google.com; path=/
OTZ=XXXXX; secure; expires=Sat, 01-Aug-2015 17:34:15 GMT; domain=plus.google.com; path=/
SAVING COOKIES
PREF=ID=1111111111111111:FF=0:TM=XXXXX:LM=XXXXX:V=1:S=XXXXX; expires=Sat, 01-Jul-2017 17:34:51 GMT; domain=.google.com; path=/
NID=XXXXX; HttpOnly; expires=Fri, 01-Jan-2016 17:34:51 GMT; domain=.google.com; path=/
OGPC=5-2:; expires=Sat, 01-Aug-2015 17:35:03 GMT; domain=.google.com; path=/我用XXXXX替换了一些密钥和号码,以避免在网上发布任何重要的内容。
下面是生成此输出的源代码:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
//Manager to allow use of cookiejar
QNetworkAccessManager* nam = new QNetworkAccessManager;
//Used for debug, prints out all cookies after each request is finished
connect(nam, SIGNAL(finished(QNetworkReply*)), this, SLOT(echo(QNetworkReply*)));
//create and assign cookiejar to nam
jar = new CookieJar();
nam->setCookieJar(jar);
//create webview and assign nam to it
webview = new QWebView();
webview->page()->setNetworkAccessManager(nam);
//Display cookies loaded from disk
const QList<QNetworkCookie> cookies = jar->getCookies();
std::cout << std::endl << "Cookies From Disk:" << std::endl << std::endl;
for(QNetworkCookie cookie: cookies)
std::cout << cookie.toRawForm().data() << std::endl;
//Load the test url
QUrl url("http://www.google.com");
webview->load(url);
//place webview on screen
ui->setupUi(this);
setCentralWidget(webview);
}
//Used for debug, prints out all cookies after each request is finished
void MainWindow::echo(QNetworkReply *reply){
const QList<QNetworkCookie> cookies2 = jar->getCookies();
std::cout << std::endl << "Cookies After HTTP:" << std::endl << std::endl;
for(QNetworkCookie cookie: cookies2)
std::cout << cookie.toRawForm().data() << std::endl;
}我的cookiejar实现的相关部分:
bool CookieJar::saveCookiesToDisk(){
std::ofstream output("cookies.dat");
this->purgeOldCookies();
if(output){
QList<QNetworkCookie> cookies = this->allCookies();
std::cout << "\nSAVING COOKIES" << std::endl << std::endl;
for(QNetworkCookie cookie: cookies)
if(!cookie.isSessionCookie()){
std::cout << cookie.toRawForm().data() << std::endl;
output << cookie.toRawForm().data() << this->COOKIE_DELIMITER;
}
output.close();
return true;
}
else{
return false;
}
}
bool CookieJar::loadCookiesFromDisk(){
std::ifstream input("cookies.dat");
if(input){
QList<QNetworkCookie> cookies;
std::string cookieData;
std::cout << "\nLOADING COOKIES" << std::endl << std::endl;
while(getline(input, cookieData, this->COOKIE_DELIMITER)){
std::cout << cookieData << std::endl;
cookies.append(QNetworkCookie(QByteArray(cookieData.c_str(), cookieData.length())));
}
this->setAllCookies(cookies);
return true;
}
else{
return false;
}
}
/**
* This function comes from the official qt demo at
* http://doc.qt.io/qt-5/qtwebkitexamples-webkitwidgets-browser-cookiejar-cpp.html
*/
void CookieJar::purgeOldCookies(){
QList<QNetworkCookie> cookies = allCookies();
if (cookies.isEmpty())
return;
int oldCount = cookies.count();
QDateTime now = QDateTime::currentDateTime();
for (int i = cookies.count() - 1; i >= 0; --i) {
if (!cookies.at(i).isSessionCookie() && cookies.at(i).expirationDate() < now)
cookies.removeAt(i);
}
if (oldCount == cookies.count())
return;
setAllCookies(cookies);
//This last line from the example was omitted as it is not relevant to the function of this project?
//emit cookiesChanged();
}任何帮助找出为什么我存储的cookie似乎被服务器忽略的话,我们将非常感激。据我所知,我正在正确地存储和发送所有cookie,所以如果我过度简化了这些身份验证cookie的工作方式,我就不会感到惊讶了。
谢谢大家抽出时间来帮我。
发布于 2015-07-02 19:29:27
我有一个“驻留日志”应用程序的工作示例,下面是load&save函数:
bool loadLoginCookie()
{
QDir cookiesDir("dir where cookie is stored");
if(! cookiesDir.exists())
{
return false;
}
QFile cookieFile(cookiesDir.path() + "/cookie.dat");
if(! cookieFile.exists())
{
return false;
}
if(! cookieFile.open(QIODevice::ReadOnly))
{
qDebug() << "Error reading the cookie file:" << cookieFile.fileName();
}
QByteArray cookieRaw = cookieFile.readAll();
cookieFile.close();
QList<QNetworkCookie> newCookies = QNetworkCookie::parseCookies(cookieRaw);
if (newCookies.count() == 0 && cookieRaw.length() != 0)
{
qDebug() << "CookieJar: Unable to parse saved cookie:" << cookieRaw;
}
QNetworkManager& myAppNetworkManager =Application::getInstance().getNetworkManager();
myAppNetworkManager.fillCookiesJar(newCookies, QUrl("theurl:443"));
foreach (QNetworkCookie cookie, newCookies)
{
if(cookie.name() == "connect.sid") //loging cookie
{
Application::getInstance().setLoginCookie(cookie); //here i save the login cookie in a class QNetworkCookie*
qDebug() << "cookie loaded";
}
else
{
qDebug() << "Error loading the login cookie.";
}
}
return true;
}
bool Application::saveLoginCookie(const QNetworkCookie &cookie)
{
QDir cookiesDir("dir where cookie must be stored");
if(! cookiesDir.exists())
{
if(! cookiesDir.mkpath("."))
{
qDebug() << "Error creating the cookies directory";
return false;
}
}
QFile cookieFile(cookiesDir.path() + "/cookie.dat");
if(! cookieFile.open(QIODevice::WriteOnly))
{
qDebug() << "Error saving the cookie file:" << cookieFile.fileName();
return false;
}
cookieFile.write(cookie.toRawForm());
cookieFile.close();
qDebug() << "Login cookie created successfully.";
return true;
});这个保存函数在登录操作之后调用:
QVariant cookieVar = reply.header(QNetworkRequest::SetCookieHeader);//reply is the QNetworkReply returned by the login operation
if(cookieVar.isValid())
{
QList<QNetworkCookie> cookies = cookieVar.value<QList<QNetworkCookie> >();
foreach (QNetworkCookie cookie, cookies)
{
if(cookie.name() == "connect.sid") //loging cookie
{
if(! saveLoginCookie(cookie))
{
qDebug() << "Error saving login cookie";
}
}
}
}
else
{
qDebug() << "Login cookie not valid";
}
}我知道这不是cookieJar的重新实现,但它可能会给您灵感。如果你做不到,我们可以进一步讨论。
https://stackoverflow.com/questions/31191545
复制相似问题