2015-07-02 3 views
0

Обои по программе (в случае, который помогает):Оставаться в Печенье с Qt Webview

Я пытаюсь сделать простую обертку, чтобы пойти вокруг «веб-приложений», чтобы дать им некоторые взгляды/чувствовать + изоляцию, которую приносит традиционное приложение. Я понимаю, что использование веб-технологий упрощает разработку для кросс-платформы (особенно когда речь заходит о пользовательском интерфейсе), но мне не нравится, как она стала своего рода уловкой для многих разработчиков. Я не хочу запускать программное обеспечение внутри своего веб-браузера.

Браузеры тяжелые и поддерживают широкий спектр функций, которые не имеют отношения к тому, что делает приложение, и что функция программы полностью находится на вкладке браузера, может привести к неуклюжему опыту пользователя (я смотрю на вас Bittorrent Sync для Linux). Вместо этого я предпочел бы использовать урезанный браузер, который намного легче и работает в своем изолированном пространстве, а не в экосистеме браузера.

Дополнительная функциональность может быть легко прикреплена для обеспечения более гибкого пользовательского интерфейса (например, если пользователь не запускает программу и пытается подключиться к ней через браузер, они получат коды ошибок HTTP. отдельная оболочка, программа могла бы прочитать сам код ошибки и показать некоторый предварительно загруженный html, чтобы дать более полезную ошибку, специфичную для программы).

Для этого я пытаюсь использовать Qt для создания браузера, который является просто веб-рендерингом, http-коммуникатором, поддержкой файлов cookie и некоторыми основными функциями управления (ярлыки для запуска программы вместо того, чтобы полагаться на командную строку)

ПРОБЛЕМА:

Проверка "Оставаться в" поле ничего не делает. Я уверен, что работа с остальными подписчиками заключается в том, что сервер создает аутентификацию для браузера для хранения в виде файла cookie.

Когда я вхожу в свою учетную запись google, я вижу несколько файлов cookie, созданных после входа в систему, которые, как представляется, делают именно это. Я могу иметь доступ к моим gmail, календарю и т. Д., И когда я выхожу из несекундных файлов cookie, они сохраняются на диске.

Когда я запускаю резервную копию программы, они загружаются с диска и отображаются в каждом запросе, но я не подписан в учетную запись, и ссылка на нее видна. Если я не вхожу в систему снова, старые файлы 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.

Благодарим вас за то, что уделили время, чтобы помочь мне здесь.

+0

если я добавляю строку 'webview-> page() -> networkAccessManager() -> cookieJar() -> setCookiesFromUrl (jar-> getCookies(), url);' перед вызовом 'webview-> load()' он будет помнить мою учетную запись, но требует, чтобы я снова ввел свой пароль при следующем запуске. Если я не верну свой пароль, он будет показывать знак вместо изображения учетной записи при последующих входах. – Ranind

+0

Возможно ли или желательно изменить аутентификацию на токен? –

ответ

0

У меня есть рабочий пример «оставаться вошедшего» приложения, здесь нагрузка & сохранить функции:

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"; 
    } 
} 

I знайте, что это не повторная реализация cookieJar, но это может дать вам вдохновение. Мы можем обсудить его дальше, если вы не можете заставить его работать.