首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

使用 Node.js、Mongo 和 D3 创建一个工具来分析 Twitter 用户信息(4)

使用 Node.js、Mongo 和 D3 创建一个工具来分析 Twitter 用户信息(4)

第 3 步.                设置身份验证并指定用户速率限制Twitter 的 API 具有速率限制。该限制设置了用户在某个时间段可发出的请求数量,以预防服务器上发生难以管控的需求。Twitter                建议编写您的自定义应用程序,以便使用应用程序用户自己的速率分配,而不是从单个帐户运行应用程序,比如应用程序开发人员的帐户。
例如,在用户输入一位关注者的名称时,我的 ProfileWords 应用程序会请求关注者列表。在我的应用程序中,该请求可以返回最多 1000                个帐户名称。Twitter 的速率限制允许在 15 分钟内执行 15                    次这样的请求。(在您滚动分析个人信息时,此限制似乎太小,但生活就是这样。)
第一步是对一个用户执行身份验证,以便可以调用该 API 并在该用户的个人速率限制下进行操作。
我研究了几小时,才弄明白如何使用 Node 向 Twitter 执行身份验证。尽管这是一项常见的任务(许多服务使用开放验证),但 Node                技术的变化非常快,以至于我找到的示例不适合最新的 Node OAuth 模块。
因此,我开发了一个单独的项目来分享  。该项目中的 README 文件详细介绍了使用您自己的                Twitter 开发人员信息克隆此应用程序的步骤。
以下是下面这个代码清单中使用的一般流程:
  • 在用户键入应用程序的 URL 时,系统会提示用户通过 Twitter 进行登录。
  • 当用户单击 Login 时,他会被重定向到一个 Twitter 身份验证页面。
  • 在用户登录到 Twitter 时,会被定向回一个预先编写的回调页面(在本例中为词汇云页面)。这个回调 URL 编写在子项目的                    server.js 文件中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
var express = require('express');
var util = require('util');
var oauth = require('oauth');
var http = require('http');
var cookieParser = require('cookie-parser');
var session = require('express-session');
var errorHandler = require('errorhandler');
var logger = require('morgan');


var app = express();
var server = http.createServer(app);

// Get your credentials here: https://dev.twitter.com/apps

var _twitterConsumerKey = "YOUR TWITTER CONSUMER KEY";
var _twitterConsumerSecret = " YOUR TWITTER CONSUMER SECRET";

var consumer = new oauth.OAuth(
    "https://twitter.com/oauth/request_token",
    "https://twitter.com/oauth/access_token",
    _twitterConsumerKey, _twitterConsumerSecret, "1.0A", "http://127.0.0.1:8080/sessions/callback", "HMAC-SHA1");

app.use(errorHandler({ dumpExceptions: true, showStack: true }));
app.use(logger());
app.use(cookieParser());
app.use(session({ secret: "very secret" }));

app.use(function(req, res, next){
  var err = req.session.error,
      msg = req.session.success;
      delete req.session.error;
      delete req.session.success;
  res.locals.message = '';
  if (err) res.locals.message = '<p class="msg error">' + err + '</p>';
  if (msg) res.locals.message = '<p class="msg success">' + msg + '</p>';
  next();
});

app.get('/sessions/connect', function(req, res){
  consumer.getOAuthRequestToken(
      function(error, oauthToken, oauthTokenSecret, results){
        if (error) {
            res.send("Error getting OAuth request token : " +
                     util.inspect(error), 500);
    } else {
      req.session.oauthRequestToken = oauthToken;
      req.session.oauthRequestTokenSecret = oauthTokenSecret;
      res.redirect("https://twitter.com/oauth/authorize?oauth_token="+req.session.oauthRequestToken);
      console.log( 'get sessions connect' );
    }
  });
});

app.get('/sessions/callback', function(req, res){
  util.puts(">>"+req.session.oauthRequestToken);
  util.puts(">>"+req.session.oauthRequestTokenSecret);
  util.puts(">>"+req.query.oauth_verifier);
  consumer.getOAuthAccessToken( req.session.oauthRequestToken, req.session.oauthRequestTokenSecret, req.query.oauth_verifier,
    function(error, oauthAccessToken, oauthAccessTokenSecret, results) {
    if (error) {
    res.send("Error getting OAuth access token : " + util.inspect(error)
            + "["+oauthAccessToken+"]"+ "[" +oauthAccessTokenSecret
            + "]" + "[" + util.inspect(results)+"]", 500);
    } else {
      req.session.oauthAccessToken = oauthAccessToken;
      req.session.oauthAccessTokenSecret = oauthAccessTokenSecret;

      console.log( 'get sessions callback' );
      res.redirect('/home');
    }
  });
});

var tAPI = "https://api.twitter.com/1.1/account/verify_credentials.json";

app.get('/home', function(req, res){
    consumer.get( tAPI, req.session.oauthAccessToken,
                 req.session.oauthAccessTokenSecret,
                 function (error, data, response) {
      if (error) {
          console.log( 'error\n' );
          console.log( error );
          res.redirect('/sessions/connect');
      } else {
          var parsedData = JSON.parse(data);
          console.log( parsedData );
          res.send('You are signed in: ' + parsedData.screen_name);
      }
    });
});

app.get('*', function(req, res){
    res.redirect('/home');
});

app.listen(8080);




此项目中的 README 文件 列出了使用此框架代码实现您自己的 Twitter                身份验证的步骤。/sessions/connect 路径将用户引导至用户的安全网站上的 Twitter 登录对话框,并将用户返回到                /sessions/callback 路径。您可以根据指示使用自己的 Twitter 凭据,这至关重要。
在 ProfileWords 项目内,我采用了同样的身份验证方法并将它合并到了 app.js 文件中。
用户经过身份验证后,您就可以从 Twitter 获取这个人的更多信息。信息非常多,包括用户的用户名、地理位置和用户在其 Twitter                页面的设计中的颜色选择。
关键信息是用户的私钥,因为他们对 Twitter 的后续查询需要使用找些信息。您可以在以下代码清单中看到该密钥。我将该数据存储在一个 Mongo                数据库中,以便在以后代表用户进行使用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
app.get('/profilewords.html', function(req, res){

       var twitterVerification = "https://api.twitter.com/1.1/account/verify_credentials.json";
       var token = req.session.oauthAccessToken;
       var secret = req.session.oauthAccessTokenSecret;

       consumer.get( twitterVerification, token, secret, function (error, data, response) {
           if( error ){
               console.log( 'Twitter verification error\n' );
               console.log( error );
               res.redirect('/sessions/connect');

           } else {

               var parsedData = JSON.parse(data);
                           
               var person = ( {'name':parsedData.screen_name,
                               'oauth_access_token': req.session.oauthAccessToken,
                               'oauth_access_token_secret': req.session.oauthAccessTokenSecret } );

               var collection = followersDatabase.collection( 'tokens' );

               collection.remove( { 'name':parsedData.screen_name }, errorHandler );

               collection.insert( person, {safe:true}, errorHandler );

               res.sendfile('profilewords.html');
           }
       });
   });

返回列表