基于 Steem Connect V2 开发应用之在页面之间传递Access Token
此帖子算是@skenan大神帖子基于 Steem Connect V2 开发应用的一个补充,在写作的过程中也得到了@skenan的指导。如果之前没有做过相关的开发,请先移步基于 Steem Connect V2 开发应用。本文默认读者对Steem Connect有一定了解,并且对Angular(一个js库)有一定了解。
最近和@streemthinkcom一起做了一点开发,想创建一个我们自己的应用,为了更方便用户使用,我们选用了@skenan推荐的steemconnect的V2版本进行验证。@skanen给出的源码的功能已经非常完整了,但缺少了一个问题的阐述。所以本教程最终就一个问题。
1、问题的提出
在@skenan的帖子中写到:
以提供的Angular为例,需要修改 app.js, 适配自己的app
sc2.init({ app: 'cnsteem.app', callbackURL: 'http://localhost:8080/', scope: ['vote', 'comment'] });
当用户授权成功后,服务器会返回一个Access Token, 通过该 token 调用 Steemconnect的API,进行点赞,评论,发帖等相关操作。
Access Token是登录成功的最重要的信息之一,但此信息没有办法在网页之间传递,导致即使登录成功之后重新打开页面又变成没有登录了。
显示如下:
可以看到,我们在第一次登录成功之后,第二次打开相同的页面,又回到没有登录的状态。说明重新打开页面后并没有读取到之前登录成功获得到Access Token
2、问题的解决方案
如果大家有做网页开发的经验,很自然的想到将Access Token存储到cookie里面。并且我翻看了busy源码,看到他们也是如此做的,所以我就放心大胆的做起来了。
为了和原代码保持更高的一致性,所以使用了angular-cookie库。话不多说,上代码:
sc2.init({
app: 'steemthink.com',
callbackURL: 'http://localhost/callback.html',
scope: ['vote', 'comment']
});
angular.module('app', ['ipCookie'])
.config(['$locationProvider', function($locationProvider){
$locationProvider.html5Mode(true);
}])
.controller('Main', function($scope, ipCookie) {
$scope.loading = false;
$scope.parentAuthor = 'skenan';
$scope.parentPermlink = 'steem-connect-v2';
$scope.accessToken = ipCookie('st_access_token');
$scope.loginURL = sc2.getLoginURL();
if ($scope.accessToken) {
sc2.setAccessToken($scope.accessToken);
sc2.me(function (err, result) {
console.log('/me', err, result);
if (!err) {
$scope.user = result.account;
$scope.metadata = JSON.stringify(result.user_metadata, null, 2);
$scope.$apply();
}
});
}
$scope.isAuth = function() {
return !!$scope.user;
};
$scope.loadComments = function() {
steem.api.getContentReplies($scope.parentAuthor, $scope.parentPermlink, function(err, result) {
if (!err) {
$scope.comments = result.slice(-5);
$scope.$apply();
}
});
};
$scope.comment = function() {
$scope.loading = true;
var permlink = steem.formatter.commentPermlink($scope.parentAuthor, $scope.parentPermlink);
sc2.comment($scope.parentAuthor, $scope.parentPermlink, $scope.user.name, permlink, '', $scope.message, '', function(err, result) {
console.log(err, result);
$scope.message = '';
$scope.loading = false;
$scope.$apply();
$scope.loadComments();
});
};
$scope.vote = function(author, permlink, weight) {
sc2.vote($scope.user.name, author, permlink, weight, function (err, result) {
if (!err) {
alert('You successfully voted for @' + author + '/' + permlink);
console.log('You successfully voted for @' + author + '/' + permlink, err, result);
$scope.loadComments();
} else {
console.log(err);
}
});
};
$scope.updateUserMetadata = function(metadata) {
sc2.updateUserMetadata(metadata, function (err, result) {
if (!err) {
alert('You successfully updated user_metadata');
console.log('You successfully updated user_metadata', result);
if (!err) {
$scope.user = result.account;
$scope.metadata = JSON.stringify(result.user_metadata, null, 2);
$scope.$apply();
}
} else {
console.log(err);
}
});
};
$scope.logout = function() {
sc2.revokeToken(function (err, result) {
console.log('You successfully logged out', err, result);
delete $scope.user;
delete $scope.accessToken;
$scope.$apply();
});
};
})
.controller('SetCookies', ['$scope', '$location', 'ipCookie', function($scope, $location, ipCookie) {
$scope.loading = false;
$scope.accessToken = $location.search().access_token;
$scope.expiresIn = $location.search().expires_in;
if ($scope.accessToken) {
sc2.setAccessToken($scope.accessToken);
//get the details of an account
//set the cookie
ipCookie('st_access_token', $scope.accessToken,
{expirationUnit: 'seconds', expires: $scope.expiresIn * 1});
sc2.me(function (err, result) {
console.log('/me', err, result);
if (!err) {
$scope.user = result.account;
$scope.metadata = JSON.stringify(result.user_metadata, null, 2);
$scope.$apply();
}
});
}
$scope.isAuth = function() {
return !!$scope.user;
};
}]);
相比较@skenan的app.js文件,最大的差别有三点:
使用了angular-cookie.js库
增加了“SetCookies”这个Controller
在SetCookies这个Controller中,将Access Token存储到了Cookie中。
更改了Main这个Controller之中读取Access Token位置
将Main中读取Access Token从$location改变为从Cookie
3、如何使用
我将页面分为两类:
第一类为callback.html
该页为验证成功返回的页面,其功能主要是实现跳转及将Access Token存储在Cookie中,所以此页面使用的Controller为SetCookies。
<!DOCTYPE html> <html lang="en" ng-app="app"> <head> <title>Demo</title> <base href="/" /> <meta charset="UTF-8"> <meta id="viewport" name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=0"/> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> (html comment removed: [if lt IE 9]><script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]) <script src="sc2/angular.min.js"></script> <script src="sc2/angular-cookie.min.js"></script> <script src="sc2/sc2.min.js"></script> <script src="sc2/steem.min.js"></script> <script src="sc2/app.js"></script> </head> <body> <div ng-controller="SetCookies"> <div> <h3>在此页中主要是设置Cookies和跳转</h3> <a href="index.html">SteemThink</a> </div> </div> </body> </html>
没什么特殊,只要注意设置ng-controller为SetCookies就可以了。
第二类为普通页面
此类页面为普通的页面,使用的Controller为Main(类似于@skenan实现的页面)。
主要是@skenan的工作,代码我就不贴了。
4、源码及使用
最后的效果
我也将完整的源码上传到了我的github上:sc2-cookie。并做了一个示例链接:Steem Connec V2 with Cookie。此网站主要只有三个页面:
-
用于登录及功能展示,和@skenan的页面差别很小。
-
用于登录后的返回页面,主要是用于设置cookie。
-
和index.html页面内容完全一致,只是用于说明其他所有页面都可以自动登录。
这样就完全的实现了Access Token在页面间的传递工作,下面就可以实现更复杂的功能了。
你们打算写什么app呢?
作为大虾 其实刚开始的时候 就像邀请你加入的 但是因为没找到合适机会
不知道有没有兴趣?
不好意思,我想开发一个steem 竞猜的app, 就先不加入你们了
Steemthink,这个是个介绍:
https://steemit.com/steemthink/@steemthinkcom/steemthink-update-4-ios-application-and-web-client-development-progress
不过我现在就是个摇旗呐喊的,哈哈。。。