我正在用 QML 编写 Ubuntu Touch 应用程序。我想与 Trello 集成。有两种方法可以在 API 中登录 Trello,其中一种是 OAuth,我打算使用它。从 QML 执行此操作的最佳方法是什么?我宁愿不使用 C++ 后端,但如果这是唯一的方法,我愿意这样做。
答案1
您可以为 Trello 创建一个帐户插件,这样就可以从系统设置中的“在线帐户”面板创建 Trello 帐户。然后您可以使用 Ubuntu.OnlineAccounts QML 模块登录,如下所示:
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 与 Flickr 和 twitter 一样使用 OAuth 1.0,只需使用 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、客户端 ID 和密钥),以匹配您在 Trello 注册应用时设置的字段。如果一切顺利,您将能够从系统设置中的“在线帐户”面板创建 Trello 帐户。
答案2
由于 mardy 使用的方法实际上不适用于 Ubuntu Touch 上的受限应用程序,因此需要自己执行 OAuth 操作。本质上,您需要在 a 中加载登录页面,WebView
然后使用onUrlChanged
信号拦截响应以提取身份验证令牌。下面是使用StackExchange 自己的 OAuth 实现。
在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 中提取令牌并从数据库中进行存储/检查:
.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 示例升级至 QtQuick 2.0。