Как использовать 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.