我最近使用 NodeJs (Passport) 和 AngularJs 实现了类似的东西。如果您的实现有点相似,您将需要在 Twitter 中对用户进行身份验证并请求用户授权您的应用程序进行访问。
我附加了 nodejs 路由的 sn-ps、AngularJs 拦截器和 AngularJS 路由,以使这在我的实现中成为可能。护照和策略在 Passport 中有详细记录,因此我将其排除在此解决方案之外以保持简短。我在https://github.com/oredi/TwitThruSeet/ 中找到了实验性的完整实现,其中包含以下子文件夹:
- NodeJs 路由 - server/routes/routes.js
- 护照策略 - server/lib/service/passport/twitterStrategy.js
- AngularJs 路由 - webclient/js/app.js
- AngularJs 拦截器 - webclient/js/interceptors.js
在 nodejs 中,您需要创建一个中间件来验证您的请求,如
所示
app.get('/api/twitter/timeline', isLoggedIn, function (req, res) {
getTwitterTimeLine(req, function (err, data, response) {
if(err) {
res.send(err, 500);
return;
}
res.send(data);
});
});
路由使用此中间件进行身份验证,以检查用户是否已登录 Twitter 并授权您的应用。
// route middleware to make sure a user is logged in
function isLoggedIn(req, res, next) {
if (!req.isAuthenticated())
res.send(401);
else
next();
}
如果请求被授权,那么您使用令牌和密码进行调用
function getTwitterTimeLine(req, callback) {
var uri = 'https://api.twitter.com/1.1/statuses/home_timeline.json?count=';
if(req.query.count) {
uri += req.query.count;
} else {
uri += "10";
}
console.log(uri);
passport._strategies.twitter._oauth._performSecureRequest(
req.user.twitter_token,
req.user.twitter_token_secret,
'GET',
uri,
null,
null, null, function (err, data, response) {
var processedData;
if(!err) {
result = [];
var max_id, since_id;
var jsonData = JSON.parse(data);
for (var i = 0; i < jsonData.length; i++) {
var record = jsonData[i];
var place_full_name = null;
if(record.place != undefined)
place_full_name = record.place.full_name;
result.push({
id_str: record.id_str,
created_at: record.created_at,
text: record.text,
user_screen_name: record.user.screen_name,
user_name: record.user.name,
user_profile_image_url: record.user.profile_image_url,
place_full_name: place_full_name
});
}
}
callback(err, result, response);
});
}
这是获取护照以通过 Twitter 进行身份验证的途径
app.get('/auth/twitter', passport.authenticate('twitter'));
如果您使用我的实现将令牌和机密存储在 req.user 中,您将需要以下 Passport 策略
var TwitterStrategy = require('passport-twitter').Strategy;
module.exports.strategy = function(options) {
return new TwitterStrategy({
consumerKey: options.consumerKey,
consumerSecret: options.consumerSecret,
callbackURL: options.callbackURL
},
function(token, tokenSecret, profile, done) {
// asynchronous verification, for effect...
process.nextTick(function () {
profile.twitter_token = token;
profile.twitter_token_secret = tokenSecret;
return done(null, profile);
});
});}
在配置路由的 AngularJS 模块中,您需要添加一个拦截器来捕获身份验证事件并将用户重新路由到 Twitter 的授权页面
angular.module('demoApi', ['demoApiSeet.interceptors', 'ngRoute'])
.config(['twitterInterceptorProvider', '$routeProvider', '$locationProvider'
,'$httpProvider', function (twitterInterceptorProvider, $routeProvider,
$locationProvider, $httpProvider) {
twitterInterceptorProvider.RedirectUrl('/auth/twitter');
$httpProvider.interceptors.push('twitterInterceptor');
}]);
最后,您需要有一个拦截器来捕获 401 请求并重新路由到您的 nodejs 路由详述的 Twitter auth 端点。请注意我实现了 $window.location.href = authUrl;因为我需要在页面 api 调用或加载页面期间将页面路由到 Twitter auth 端点。如果手动触发身份验证,则可能不需要。
angular.module('demoApiSeet.interceptors', [])
.provider('twitterInterceptor', function() {
var redirectUrl;
this.RedirectUrl = function(value) {
redirectUrl = value;
};
this.$get = ['$q', '$location', '$window', function($q, $location, $window) {
return {
response: function(response){
return response || $q.when(response);
},
responseError: function(rejection) {
$q.when(rejection.status == 401)
if (rejection.status === 401) {
if(redirectUrl) {
$location.path(redirectUrl);
var authUrl = $location.absUrl();
$window.location.href = authUrl;
}
} else if (rejection.status === 429) {
$location.path('/error');
}
return $q.reject(rejection);
}
}
}];
})
我希望这会有所帮助,如果您需要更多信息,您可以参考完整的实现,这有点骇人听闻,因为它是一个 POC。