【问题标题】:How to use Twitter API from client side?如何从客户端使用 Twitter API?
【发布时间】:2014-06-04 17:02:50
【问题描述】:

我正在尝试使用 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,但没听懂。

感谢您的帮助,

【问题讨论】:

    标签: angularjs twitter oauth passport.js


    【解决方案1】:

    如果只需要获取时间线,可以使用ng-tweets

    如果你想要一个纯粹的客户端方法,并且你只需要拉一个时间线,你可以使用这里提供的 ng-tweets 模块:

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

    它通过抓取官方 Twitter 小部件 API 并反向工程 JSON 提要来工作,因此您不需要身份验证令牌或秘密或任何服务器端支持代码。

    免责声明

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

    【讨论】:

    • 我刚刚浏览了演示 plnkr.co/edit/gLkDBn?p=preview,但无法获得任何推文更新。我应该怎么做才能获得推文结果。
    • @Anand - 小部件的 HTML 格式已更改。随意分叉和修复。这是一个旧项目,我现在没有时间修复它。
    • 将尝试修复。
    【解决方案2】:

    我最近使用 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。

    【讨论】:

    • 这太糟糕了。您永远不应该在客户端代码中包含消费者机密。 Twitter 应该提供一种在不使用机密的情况下发出 API 请求的方法(例如,Facebook JavaScript API 允许 - 你只需要用户的访问令牌)。否则,如果没有单独的服务器,几乎不可能安全地使用 Twitter API,这意味着 TWITTER 很烂。
    【解决方案3】:

    您的所有推特请求都需要获得授权:

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

    因此您需要在上述每个文档的请求标头中传递一些 OAuth 数据

    【讨论】:

    猜你喜欢
    • 2015-11-17
    • 1970-01-01
    • 2011-02-28
    • 2013-10-15
    • 2013-11-07
    • 1970-01-01
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多