2017-01-06 5 views
1

QWebEngineView 및 QNetworkAccessManager를 사용하는 Qt 클라우드 클라이언트 응용 프로그램에서 작업 중입니다. 발생한 문제는 다음과 같습니다.Qt 5.7 QNetworkProxy가 쿠키를 고려하지 않습니다.

응용 프로그램에 사용자 정의 로그인 양식이 있습니다. 사용자 자격 증명에 따라 일련의 수동 요청 ("게시"및 "가져 오기")을 수행하여 관련 세션 쿠키를 얻습니다.

... 
    //get session cookie 
    QNetworkAccessManager accessManager; 
    connect(&accessManager, &QNetworkAccessManager::proxyAuthenticationRequired, [=] (const QNetworkProxy &proxy, QAuthenticator *authenticator){ 
     //perform proxy auth in case a proxy is set 
    }); 

    QNetworkReply * reply = Q_NULLPTR; 

    QNetworkRequest request(QUrl(/*url*/)); 
    request.setRawHeader("Content-Type", "application/x-www-form-urlencoded"); 
    request.setRawHeader("Cache-Control", "no-cache"); 

    QByteArray data(/*data for auth*/); 
    reply = accessManager.post(request,data); //ajax login 

    QEventLoop waitReplyHandler; 
    QObject::connect(reply, SIGNAL(finished()), &waitReplyHandler, SLOT(quit())); 

    //wait for reply from url 
    waitReplyHandler.exec(); 
    QVariant sessionCookie = reply->header(QNetworkRequest::SetCookieHeader); //this cookie is used to retrieve second "session cookie" 
    ... 

    //Different function - get user session cookie 
    QNetworkRequest request(QUrl(/*url*/)); 

    request.setHeader(QNetworkRequest::CookieHeader, sessionCookie); 
    QNetworkReply * reply = accessManager.get(request); 

    QEventLoop waitReplyHandler; 
    QObject::connect(reply, SIGNAL(finished()), &waitReplyHandler, SLOT(quit())); 

    //wait for reply from url 
    waitReplyHandler.exec(); 
    QString redirect = reply->header(QNetworkRequest::LocationHeader).toString(); 
    QVariant userSessionCookie = reply->header(QNetworkRequest::SetCookieHeader); 

이 후 나는 QWebEngineView에 대한 요청 인터셉터를 설정 :

void CWebEngineUrlRequestInterceptor::interceptRequest(QWebEngineUrlRequestInfo &info) 
    { 
     QByteArray sessionCookie = QByteArray(m_sessionCookie.name() + "=" + m_sessionCookie.value()); 
     QByteArray userSessionCookie = QByteArray(m_userSessionCookie.name() + "=" + m_userSessionCookie.value()); 

     QByteArray requestCookies = sessionCookie + "; " + userSessionCookie; 

     info.setHttpHeader(QByteArray("Cookie"), requestCookies); 
    } 

: 아이디어는 웹 엔진 뷰에 대한 모든 부하 호출이 매뉴얼을 얻을 쿠키를 사용하는 것입니다

interceptor = new CWebEngineUrlRequestInterceptor(sessionCookie.value<QList<QNetworkCookie>>().first(), 
                  userSessionCookie.value<QList<QNetworkCookie>>().first(), 
                  this); 
    m_tabWebview->webEngineView()->page()->profile()->setRequestInterceptor(interceptor); 
    m_tabWebview->webEngineView()->load(redirectUrl); //Obtained from "redirect" string variable from second manual request 

이 작업은 redirectUrl에로드 된 후에 완벽하게 OK입니다. 이미 웹에 로그인 한 사용자가 클라우드의 홈 페이지를 표시합니다. 그러나 QNetworkProxy를 애플리케이션에 설정하면

QNetworkProxy proxy; 
    proxy.setType(QNetworkProxy::HttpProxy); 
    proxy.setHostName(proxyUrl); 
    proxy.setPort(proxyPort.toInt()); 

    QNetworkProxy::setApplicationProxy(proxy); 

위의 시퀀스는 내 대상 URL의 로그인 페이지를 웹보기에 표시합니다. 응용 프로그램 수준 프록시 설정은 QWebEngineView에 대해 불가지론 적이어야한다고 생각합니다. 수동 요청이 작동하고 쿠키를 얻을 수 있으며 interceptRequest도 호출되지만 프록시 릴레이 후에 쿠키가 유지되지 않습니다.

QByteArray requestCookies = m_cookies.first().name() + "=" + m_cookies.first().value() + "; " + 
          m_cookies.last().name() + "=" + m_cookies.last().value(); 

    QNetworkProxy proxy(QNetworkProxy::applicationProxy()); 
    proxy.setRawHeader(QByteArray("Cookie"), requestCookies); 
    QNetworkProxy::setApplicationProxy(proxy); 
    //... 
    //check headers are set to proxy 
    QByteArray cookieVar = QNetworkProxy::applicationProxy().rawHeader(QByteArray("Cookie")); 
    if(cookieVar.isEmpty()){ 
     std::cout<<"empty cookies to proxy "; 
    } 
    else{ 
     std::cout<<cookieVar.toStdString()<<std::endl; 
    } 

로그를 확인하고, 나는 쿠키 프록시에 연결되어 있음을 볼 수 있습니다 또한 프록시 자체에 수동으로 헤더를 설정했습니다.

이 사용자 정의 로그인 메커니즘은 세션 쿠키의 만료 시간보다 긴 시간 인터넷 연결이없는 경우 자동 로그인을 처리하도록 구현됩니다. 수동으로 얻은 세션 쿠키를 사용하도록 응용 프로그램 수준 프록시를 어떻게 설정할 수 있습니까?

미리 감사드립니다.

답변

0

프록시 인증 메커니즘과 관련된 웹 엔진 프레임 워크의 버그 인 것 같습니다. 그러나 해결 방법을 찾았습니다. QWebEnginePage :: proxyAuthenticationRequired가 호출되면 authenticator 객체에 대한 데이터가 설정된 후 requestUrl 매개 변수에 다시 load를 호출합니다.

connect(app->webview()->page(), &QWebEnginePage::proxyAuthenticationRequired, [=] (const QUrl &requestUrl, QAuthenticator *authenticator, const QString &proxyHost){ 
    proxyAuthSequence(authenticator, proxyHost); 
    app->webview()->load(requestUrl); 
}); 

이상형은 초기로드를 더미로드로만 처리하여 인증 데이터를 설정 한 다음 다시로드합니다. 후속로드 호출은 더 이상이 신호를 트리거하지 않습니다. 기본적으로 문제는 인증 메커니즘입니다.

버그도 Qt에 제출되었습니다. https://bugreports.qt.io/browse/QTBUG-58121