Search code examples
c++qtqnetworkaccessmanager

Login to website using Qt


I need to login to a website to retrieve the source code of a page. How would I do this using Qt?

I'm not familiar with how QUrl and QNetworkAcessManager work, but I was able to write code that would allow me to download the source code for any page not behind a login form.

This is what I have so far. I end up just downloading the source for the redirect page:

test = new QNetworkAccessManager(this);
QUrl URL = QUrl("http://website.com/page");
URL.setUserName("user");
URL.setPassword("password");
test->get(QNetworkRequest(URL));

Edit:

QByteArray loginData("username=user&password=password");
QNetworkRequest request(QUrl("http://website.com/login/index.php"));
manager->post(request,loginData);

QUrl URL = QUrl("http://website.com/mod/resource/view.php?id=114198");
manager->get(QNetworkRequest(URL));

I am still retrieving a 303 reply.

The page is on Moodle, which uses a HTTP POST login form.

I've also tried with a different site. POST works but I get the source code of the login page with the login form filled out. Not sure how to get the page after logging in.


Solution

  • This was my solution, for logging into a particular website and retrieving a file. I was getting redirected multiple times before reaching the destination. I test HTTP status codes until I get the final reply. I also test to see if the final URL is the one I requested and not some home page behind the login page. This is because I am downloading a file.

    QByteArray loginData;
    loginData.append("username="+(ui->lineEdit_2->text())+"&password="+(ui->lineEdit_3->text())+"&action=login");
    
    cookiesHandler* test = new cookiesHandler(this);
    QUrl request("http://website.com");
    test->sendPostRequest(request, loginData);
    

    Cookies Handler Class

    class cookiesHandler: public QObject{
        Q_OBJECT
    
    public:
        cookiesHandler(QObject *parent = 0) : QObject(parent){
            mManager = new QNetworkAccessManager(this);
            mManager->setCookieJar(new QNetworkCookieJar(this));
    connect(mManager, SIGNAL(finished(QNetworkReply*)), SLOT(replyFinished(QNetworkReply*)));
        }
    
        void sendPostRequest(const QUrl &url, const QByteArray &data){
            mUrl = url;
            login = data;
            QNetworkRequest r(mUrl);
            mManager->post(r, data);
        }
    
        void sendGetRequest(const QUrl &url)
        {
            mUrl = url;
            test = mUrl;
            QNetworkRequest r(mUrl);
            mManager->get(r);
        }
    
    
    
    
        virtual ~cookiesHandler(){}
    
    private slots:
        void replyFinished(QNetworkReply *reply){
            if (reply->error() != QNetworkReply::NoError){
                qWarning() << "ERROR:" << reply->errorString();
                return;
            }
    
    
    
    
            //Cookies//
            QList<QNetworkCookie>  cookies = mManager->cookieJar()->cookiesForUrl(mUrl);
            qDebug() << "COOKIES for" << mUrl.host() << cookies;
    
            QString str;
            QDebug dStream(&str);
    
            dStream << mUrl.host() << cookies;
    
            //End Cookies//
    
    
            int v = reply->attribute(QNetworkRequest::HttpStatusCodeAttribute).toInt();
                    if (v >= 200 && v < 300) // Success
                    {
                        getFile(reply);
                         // Here we got the final reply
                       return;
                    }
                    else if (v >= 300 && v < 400) // Redirection
                    {
                        /* Use Cookies for Login */
                    qDebug() << "REDIRECTING";
                    rUrl = reply->attribute(QNetworkRequest::RedirectionTargetAttribute).toUrl();
    
                    if(rUrl != mUrl)
                     {
                        mManager->post(QNetworkRequest(rUrl),login);
                        return;}
    
                    out << QString("redirected: " + rUrl.toEncoded()) << endl;
    
                        QNetworkRequest r(mUrl);
                        QVariant var;
                        var.setValue(cookies);
    
                        r.setHeader(QNetworkRequest::CookieHeader, var);
                        mManager->get(r);
                        return;
    
                    }
    
    
    
    
        }