Как использовать OAuth из приложения Ubuntu Touch?

Я пишу приложение Ubuntu Touch в QML. Я хотел бы интегрироваться с Trello. Существует два способа входа в Trello в API, один из которых - OAuth, который я планирую использовать. Каков наилучший способ сделать это из QML? Я бы предпочел не использовать бэкэнд C++, но я готов это сделать, если это единственный способ.

2 ответа

Вы можете создать плагин учетной записи для Trello, чтобы учетную запись Trello можно было создать из панели "Онлайн-учетная запись" в Системных настройках. Вы можете использовать модуль QML Ubuntu.OnlineAccounts для входа в систему, например:

import QtQuick 2.0
import Ubuntu.OnlineAccounts 0.1

Rectangle {
    width: 400
    height: 300

    AccountServiceModel {
        id: accounts
        service: "trello-board"
    }
    ListView {
        id: listView
        anchors.fill: parent
        model: accounts
        delegate: Item {
            width: parent.width
            height: 60
            AccountService { 
                id: accts
                objectHandle: accountServiceHandle
                onAuthenticated: { console.log("Access token is " + reply.AccessToken) }
                onAuthenticationError: { console.log("Authentication failed, code " + error.code) }
            }    
            Text {
                anchors.fill: parent
                text: providerName + ": " + displayName
                MouseArea {
                    anchors.fill: parent
                    onClicked: accts.authenticate(null)
                }
            }
        }
    }
}

Этот код даст вам токен OAuth. Для того, чтобы создать учетную запись, вам необходимо создать следующие файлы:

  • /usr/share/accounts/providers/trello.provider
  • /usr/share/accounts/services/trello-board.service
  • /usr/share/accounts/qml-plugins/trello/Main.qml

Учитывая, что Trello использует OAuth 1.0, например Flickr и twitter, просто создайте вышеуказанные файлы, используя версию twitter или flickr в качестве шаблона, и изменяйте их по мере необходимости (для файла.service вы можете использовать flickr-sharing.service); в trello.provider вам нужно изменить конечные точки API следующим образом:

<setting name="RequestEndpoint">https://trello.com/1/OAuthGetRequestToken</setting>
<setting name="TokenEndpoint">https://trello.com/1/OAuthGetAccessToken</setting>
<setting name="AuthorizationEndpoint">https://trello.com/1/OAuthAuthorizeToken</setting>

И, конечно же, измените другие поля (URL-адрес обратного вызова, идентификатор клиента и секретный), чтобы они соответствовали тем, которые вы указали при регистрации приложения в Trello. Если все пройдет хорошо, вы сможете создать учетную запись Trello на панели "Онлайн-учетные записи" в Системных настройках.

Поскольку подход, который использует Марди, на самом деле недоступен для приложений в Ubuntu Touch, необходимо выполнить танец OAuth самостоятельно. По сути, вам нужно загрузить страницу входа в WebView а затем перехватить ответ, используя onUrlChanged сигнал для извлечения токена авторизации. Ниже приведен пример использования собственной реализации OAuth в StackExchange.

В OAuth.qml:

import QtQuick 2.0
import QtWebKit 3.0
import "OAuth.js" as OAuth

Rectangle {
    height: 750
    width: 500

    Text {
        id: nextState
        visible: false
        anchors.centerIn: parent
        text: "Log in successful!"
    }

    Item {
        id: stackOAuth
        property string nextState: "AuthDone"
        anchors.fill: parent
        Component.onCompleted: OAuth.checkToken()
        property string token: ""
        WebView {
            id: loginView
            visible: false
            anchors.fill: parent
            onUrlChanged: OAuth.urlChanged(url)
        }
        Rectangle {
            height: 50
            width: parent.width
            anchors.left: parent.left
            anchors.right: parent.right
            anchors.bottom: parent.bottom
            Text {
                text: loginView.url
            }
        }

        states: [
            State {
                name: "Login"
                PropertyChanges {
                    target: loginView
                    visible: true
                    url: "https://stackexchange.com/oauth/dialog"+
                         "?redirect_uri=https://stackexchange.com/oauth/login_success"+
                         "&client_id=YOUR_CLIENT_ID&scope=read_inbox"
                }
            },
            State {
                name: "AuthDone"
                PropertyChanges {
                    target: loginView
                    visible: false
                    opacity: 0
                }
                PropertyChanges {
                    target: nextState
                    visible: true
                }
            }
        ]
    }
}

Затем в OAuth.js у вас есть код для извлечения токена из url и хранения / проверки handel из вашей базы данных:

.import QtQuick.LocalStorage 2.0 as Sql

function urlChanged(url) {
    var authorized = false;
    var mUrl = url.toString();
    var token = "";
    if (mUrl.indexOf("https://stackexchange.com") > -1) {
        var query = mUrl.substring(mUrl.indexOf('#') + 1);
        var vars = query.split("&");
        for (var i=0;i<vars.length;i++) {
            var pair = vars[i].split("=");
            if (pair[0] == "access_token") {
                authorized = true;
                token = pair[1];
                console.log("Found token: " + token)
                saveToken(token);
            }
        }
    }
    if (authorized) {
        stackOAuth.token = token;
        stackOAuth.state = "AuthDone";
    }
}

function saveToken(token) {
    console.log("Saving...")
    var db = Sql.LocalStorage.openDatabaseSync("Token", "1.0", "the token", 1);
    var dataStr = "INSERT INTO Token VALUES(?)";
    var data = [token];
    db.transaction(function(tx) {
        tx.executeSql('CREATE TABLE IF NOT EXISTS Token(token TEXT)');
        tx.executeSql(dataStr, data);
    });
}

function checkToken() {
    var db = Sql.LocalStorage.openDatabaseSync("Token", "1.0", "the token", 1);
    var dataStr = "SELECT * FROM Token";
    db.transaction(function(tx) {
        tx.executeSql('CREATE TABLE IF NOT EXISTS Token(token TEXT)');
        var rs = tx.executeSql(dataStr);
        if (rs.rows.item(0)) {
            stackOAuth.token = rs.rows.item(0).token
            stackOAuth.state = "AuthDone"
            console.log("Auth done...")
        } else {
            stackOAuth.state = "Login"
            console.log("Logging in....")
        }
    });
}

Этот пример (более или менее) является портом старого примера QtQuick 1.0 от Nokia до QtQuick 2.0.

Другие вопросы по тегам