基于 Steem Connect V2 开发应用之在页面之间传递Access Token

in #cn7 years ago

此帖子算是@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是登录成功的最重要的信息之一,但此信息没有办法在网页之间传递,导致即使登录成功之后重新打开页面又变成没有登录了。

显示如下:

no_cookie.gif

可以看到,我们在第一次登录成功之后,第二次打开相同的页面,又回到没有登录的状态。说明重新打开页面后并没有读取到之前登录成功获得到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、源码及使用

最后的效果

add_cookies.gif

我也将完整的源码上传到了我的github上:sc2-cookie。并做了一个示例链接:Steem Connec V2 with Cookie。此网站主要只有三个页面:

  • index.html

    用于登录及功能展示,和@skenan的页面差别很小。

  • callback.html

    用于登录后的返回页面,主要是用于设置cookie。

  • testpage.html

    和index.html页面内容完全一致,只是用于说明其他所有页面都可以自动登录。

这样就完全的实现了Access Token在页面间的传递工作,下面就可以实现更复杂的功能了。

Sort:  

你们打算写什么app呢?

作为大虾 其实刚开始的时候 就像邀请你加入的 但是因为没找到合适机会
不知道有没有兴趣?

不好意思,我想开发一个steem 竞猜的app, 就先不加入你们了

Steemthink,这个是个介绍:
https://steemit.com/steemthink/@steemthinkcom/steemthink-update-4-ios-application-and-web-client-development-progress

不过我现在就是个摇旗呐喊的,哈哈。。。

Coin Marketplace

STEEM 0.17
TRX 0.15
JST 0.028
BTC 62345.27
ETH 2427.57
USDT 1.00
SBD 2.49