如何从客户端使用Twitter API?

时间:2014-04-20 14:44:24

标签: angularjs twitter oauth passport.js

我试图通过angularjs和护照从twitter获取信息。

我已经使用护照js通过OAuth进行了身份验证 - 它运行良好 - 在会话中保存了用户信息。

现在我尝试在任何端点(包括V1.1和V1)的twitter API上运行任何GET命令,但它一直在抱怨授权。

示例:在我的控制器中执行

        $http.jsonp(https://api.twitter.com/1/statuses/user_timeline.json, {

        })

给我一​​个错误:

        GET https://api.twitter.com/1/statuses/user_timeline.json 401 (Unauthorized)

此命令在twitter控制台中有效(我使用jsonp来避免跨域问题)。

我是否应该使用此GET请求手动传递任何其他标头 - s.a auth_token等?

或者为什么它不起作用?我是否应该利用我已经使用API​​进行身份验证的事实?我已经红了https://dev.twitter.com/docs/auth/authorizing-request,但没有被人理解。

感谢帮助,

3 个答案:

答案 0 :(得分:4)

我最近使用NodeJs(Passport)和AngularJs实现了类似的功能。如果您的实现有点类似,则需要在Twitter中对用户进行身份验证,并请求用户授权您的应用程序进行访问。

我附加了nodejs路由,AngularJs拦截器和AngularJS路由的片段,以便在我的实现中实现这一点。护照和策略在Passport中有很好的记录,所以我将它从这个解决方案中删除以保持简短。我的完整实现是实验性的,可以在https://github.com/oredi/TwitThruSeet/中找到以下子文件夹:

  • NodeJs routing - server / routes / routes.js
  • 护照策略 - server / lib / service / passport / twitterStrategy.js
  • AngularJs routing - 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。

答案 1 :(得分:2)

如果您只需要获得时间表,则可以使用ng-tweets

如果您想要纯客户端方法,并且只需要提取时间线,则可以使用此处提供的ng-tweets模块:

https://github.com/forwardadvance/ng-tweets

它的工作原理是抓取官方的Twitter小部件API,并对JSON提要进行逆向工程,因此您不需要身份验证令牌或机密或任何服务器端支持代码。

声明

我是这个模块的作者。我写它来解决这个问题,不希望暴露oauth数据客户端,或者使用官方小部件HTML。

答案 2 :(得分:1)

您的Twitter请求需要获得授权:

https://dev.twitter.com/docs/auth/authorizing-request

因此,您需要在上面的

文档的请求标头中传递一些OAuth数据