PenguinがWorkWorkする blog

ネット上で気になることや、android等について書くブログ

oauthソース(Qt)

超めんどかった・・・。


メモ代わりにソース載せておきます。


関数化してないし、定義ファイルもできれば別に書きたかった。
あと、クラス化して分割ファイルもしたかった。

でも、考えるより先に実行を優先してこうなりました。
一度理解するために書いたようなもんです。
これを使って作りたいものはあるので、ある程度書き直してoauth部分は公開する予定です。
だって、Qt用のoauthライブラリないんだもん・・・。
車輪を再発明するだなんてあほらしい。


さて、

かれこれ、C++の学習を始めて2か月かかりましたが一応C++は書けるようになりましたといっていいのかな。

構文覚えた。
テンプレート覚えた。
クラス化覚えた。
メソット化覚えた。
イテレータ覚えた。



それでは寝ます・・・。


mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTextEdit>
#include <QPair>
#include <QList>
#include <QNetworkAccessManager>
#include <QNetworkRequest>
#include <QNetworkReply>
#include <QMessageAuthenticationCode>
#include <QCryptographicHash>
#include <QDateTime>
#include <QUrl>
#include <QUrlQuery>
#include <QWebView>
#include <QEventLoop>

#include <QDebug>



namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    QUrlQuery getRequestToken();
    ~MainWindow();

private slots:
    void on_BtnInPin_clicked();


    void on_Btnoauth_clicked();

    void on_btnTweet_clicked();

private:
    Ui::MainWindow *ui;
    QNetworkAccessManager* manager;
    QTextEdit* tedTweet;
    QTextEdit* txtInPin;

//Twitter用パラメータ
    QMap<QString,QString> Params;
    QString consumer_key;
    QString consumer_secret;
    QString oauth_nonce;
    QString oauth_signature_method;
    QString oauth_timestamp;
    QString oauth_vertion;

    QString oauth_token;
    QString oauth_token_secret;
    QString oauth_verifier;

    QString access_token;
    QString access_token_secret;

    QString request_token_url;
    QString authorize_url;
    QString access_token_url;
    QString update_url;

    QEventLoop eventLoop;
};

#endif // MAINWINDOW_H

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    qsrand(QDateTime::currentMSecsSinceEpoch());
    w.show();

    return a.exec();
}

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    tedTweet = this->ui->tedTweet;
    txtInPin = this->ui->txtInPin;
    tedTweet = this->ui->tedTweet;

    consumer_key = "";
    consumer_secret = "";
    oauth_nonce = QString::number(qrand());
    oauth_signature_method = "HMAC-SHA1";
    oauth_timestamp = QString::number(QDateTime::currentMSecsSinceEpoch()/1000);
    oauth_vertion = "1.0";

    request_token_url = "https://api.twitter.com/oauth/request_token";
    authorize_url     = "https://api.twitter.com/oauth/authorize";
    access_token_url  = "https://api.twitter.com/oauth/access_token";
    update_url        = "https://api.twitter.com/1.1/statuses/update.json";
    manager = new QNetworkAccessManager();
    connect(ui->btnexit, SIGNAL(clicked()),this,SLOT(close()));

    connect(manager, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

void MainWindow::on_BtnInPin_clicked()
{

    //パラメータを作成
    //    QList<QPair<QString, QString> > Params;
    //    Params.append(qMakePair(QString("oauth_consumer_key"), consumer_key));
    //    Params.append(qMakePair(QString("oauth_nonce"), oauth_nonce));
    //    Params.append(qMakePair(QString("oauth_signature_method"), oauth_signature_method));
    //    Params.append(qMakePair(QString("oauth_timestamp"), oauth_timestamp));
    //    Params.append(qMakePair(QString("oauth_vertion"), oauth_vertion));


    Params["oauth_consumer_key"]     = consumer_key;
    Params["oauth_nonce"]            = oauth_nonce;
    Params["oauth_signature_method"] = oauth_signature_method;
    Params["oauth_timestamp"]        = oauth_timestamp;
    Params["oauth_vertion"]          = oauth_vertion;
    //HMAC_SHA1のkeyを作成
    QString key = consumer_secret + "&";

    QUrlQuery RequestQuery;
    QMapIterator<QString,QString> itr(Params);
    while (itr.hasNext()) {
        itr.next();
        RequestQuery.addQueryItem(itr.key(),itr.value());
    }
    //signatureを作成
    //RequestQuery.setQueryItems(Params);
    QString signature =  "GET&" +
            request_token_url.toUtf8().toPercentEncoding() +
            "&" +
            RequestQuery.toString().toUtf8().toPercentEncoding();

    //signatureをハッシュ化
    QString oauth_signature = QMessageAuthenticationCode::hash (
                signature.toUtf8(),
                key.toUtf8(),
                QCryptographicHash::Sha1).toBase64().toPercentEncoding();

    //signatureをパラメータに追加
    //   Params.append(qMakePair(QString("oauth_signature"), oauth_signature));
    RequestQuery.addQueryItem("oauth_signature",oauth_signature);

    //TokenURLとパラメータをセットしてクエリを作成
    QUrl message(request_token_url);
    //    RequestQuery.setQueryItems(Params);
    message.setQuery(RequestQuery);
    QUrl url(message);
    QNetworkRequest request(url);

    //クエリをtwitterに送ってRequest_token取得
    //QEventLoop eventLoop;
    QNetworkReply* reply = manager->get(request);
    //connect(manager, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
    eventLoop.exec();

    //oauth_tokenとoauth_token_secretを取得
    QUrlQuery oauth_reply;
    oauth_reply.setQuery(QString::fromUtf8(reply->readAll()));
    oauth_token = oauth_reply.queryItemValue("oauth_token");
    oauth_token_secret = oauth_reply.queryItemValue("oauth_token_secret");
    //QWebView* webView = new QWebView;
    QWebView* webview = new QWebView;
    QUrlQuery request_pin;
    QUrl oauth_url(authorize_url);
    request_pin.addQueryItem("oauth_token",oauth_token);
    oauth_url.setQuery(request_pin);
    webview->load(QUrl(oauth_url));
    webview->show();
}

void MainWindow::on_Btnoauth_clicked()
{
    //パラメータを作成
    oauth_nonce = QString::number(qrand());
    oauth_timestamp = QString::number(QDateTime::currentMSecsSinceEpoch()/1000);
    oauth_verifier = txtInPin->toPlainText();


    Params["oauth_consumer_key"]     = consumer_key;
    Params["oauth_nonce"]            = oauth_nonce;
    Params["oauth_signature_method"] = oauth_signature_method;
    Params["oauth_timestamp"]        = oauth_timestamp;
    Params["oauth_vertion"]          = oauth_vertion;
    Params["oauth_token"]            = oauth_token;
    Params["oauth_verifier"]         = oauth_verifier;

    //keyを作成
    QString key = consumer_secret +
            "&"+
            oauth_token_secret;

    //Signatureの作成
    QUrlQuery RequestQuery;
    QMapIterator<QString,QString> itr(Params);
    while (itr.hasNext()) {
        itr.next();
        RequestQuery.addQueryItem(itr.key(),itr.value());
    }
    qDebug() << "fuji01 test:" << RequestQuery.toString();
    QString signature =  "GET&" +
            access_token_url.toUtf8().toPercentEncoding() +
            "&" +
            RequestQuery.toString().toUtf8().toPercentEncoding();

    //signatureをハッシュ化
    QString oauth_signature = QMessageAuthenticationCode::hash (
                signature.toUtf8(),
                key.toUtf8(),
                QCryptographicHash::Sha1).toBase64().toPercentEncoding();

    //パラメータにsignatureを追加
    RequestQuery.addQueryItem("oauth_signature",oauth_signature);

    //URLをセット
    QUrl url(access_token_url);
    url.setQuery(RequestQuery);
    QNetworkRequest request(url);

    //ヘッダ追加
    //request.setHeader(QNetworkRequest::ContentTypeHeader, "application/x-www-form-urlencoded");
    request.setRawHeader(QString("Authorization").toUtf8(),QString("OAuth").toUtf8());
    //QEventLoop eventLoop;
    QNetworkReply* reply = manager->get(request);
    //connect(manager, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
    eventLoop.exec();
    QByteArray Response = reply->readAll();
    tedTweet->setText(QString::fromUtf8(Response));

    QUrlQuery oauth_reply;
    oauth_reply.setQuery(QString::fromUtf8(Response));
    oauth_token = oauth_reply.queryItemValue("oauth_token");
    oauth_token_secret = oauth_reply.queryItemValue("oauth_token_secret");
    qDebug() << "oauth_token_secret :" << oauth_token_secret;
}

void MainWindow::on_btnTweet_clicked()
{
    //パラメータを作成
    oauth_nonce = QString::number(qrand());
    oauth_timestamp = QString::number(QDateTime::currentMSecsSinceEpoch()/1000);
//    QString tweet = tedTweet->toPlainText();//.toUtf8().toPercentEncoding();
    QString tweet = "test"; //tedTweet->toPlainText();//.toUtf8().toPercentEncoding();


    Params.remove("oauth_verifier");
    Params["oauth_consumer_key"]     = consumer_key;
    Params["oauth_nonce"]            = oauth_nonce;
    Params["oauth_signature_method"] = oauth_signature_method;
    Params["oauth_timestamp"]        = oauth_timestamp;
    Params["oauth_vertion"]          = oauth_vertion;
    Params["oauth_token"]            = oauth_token;
    Params["status"]                 = tweet;
    //PIN削除


    //keyを作成
    QString key = QString("%1&%2").arg(consumer_secret).arg(oauth_token_secret);
    //Signatureの作成
    QUrlQuery RequestQuery;
    QMapIterator<QString,QString> itr(Params);
    while (itr.hasNext()) {
        itr.next();
        RequestQuery.addQueryItem(itr.key(),itr.value());
    }
    qDebug()<<"Signature1 :" << RequestQuery.toString();
    QString signature =  "POST&" +
            update_url.toUtf8().toPercentEncoding() +
            "&" +
            RequestQuery.toString(QUrl::FullyEncoded).toUtf8().toPercentEncoding();
    qDebug()<<"Signature2 :" << signature;
    //signatureをハッシュ化
    QString oauth_signature = QMessageAuthenticationCode::hash (
                signature.toUtf8(),
                key.toUtf8(),
                QCryptographicHash::Sha1).toBase64().toPercentEncoding();
    //パラメータにsignatureを追加
    Params["oauth_signature"] = oauth_signature.toUtf8().toPercentEncoding();

    //URLをセット
    QUrl url(update_url);
    QNetworkRequest request(url);

    //ヘッダ作成前にstatusを削除
    Params.remove("status");

    //ヘッダ作成
    QMapIterator<QString,QString> itr2(Params);
    QString params_header;

    while (itr2.hasNext()) {
        itr2.next();
        params_header +=
                QString("%1=%2,").arg(itr2.key(),itr2.value());
    }
    params_header.resize(params_header.size() -1);
    qDebug()<< "header1 :"<< params_header;
    //ヘッダ追加
    request.setHeader(QNetworkRequest::ContentTypeHeader, QByteArray("application/x-www-form-urlencoded"));
    request.setRawHeader(QByteArray("Authorization"), QByteArray("OAuth ").append(params_header));
    //QEventLoop eventLoop;
    QNetworkReply* reply = manager->post(request,QByteArray("status=") + tweet.toUtf8().toPercentEncoding());
    //connect(manager, SIGNAL(finished(QNetworkReply*)), &eventLoop, SLOT(quit()));
    eventLoop.exec();
    QByteArray result = reply->readAll();
    tedTweet->setText(QString::fromUtf8(result));


}