在使用OAuth和Twitter Ruby宝石时,持续收到“OAuth::Unauthorized”错误

41

我正在使用 Ruby 的 Twitter gem 和 OAuth 来获取用户的 Twitter 帐户访问权限。在我的代码中,我有:

unless @user.twitter_authd?
      oauth = Twitter::OAuth.new('token', 'secret')
      session[:twitter_request_token] = oauth.request_token.token
      session[:twitter_request_secret] = oauth.request_token.secret
      @twitter_auth_url = oauth.request_token.authorize_url
    end

这里的token和secret填入了我的真实token和secret。当我点击@twitter_auth_url链接时,我被带到Twitter并被要求授权。我点击允许,然后Twitter将我重定向到我的回调URL http://www.mydomain.com/twitter_callback/?oauth_token=fmy2aMvnjVgaFrz37bJ4JuB8r5xN79gsgDQRG4BNY,然后触发以下代码:

oauth = Twitter::OAuth.new('token', 'secret')

    logger.info("session[:twitter_request_token] = #{session[:twitter_request_token]}")
    logger.info("session[:twitter_request_secret] = #{session[:twitter_request_secret]}")

    oauth.authorize_from_request(session[:twitter_request_token], session[:twitter_request_secret])
    session[:twitter_request_token] = nil
    session[:twitter_request_secret] = nil

    @user.update_attributes({
      :twitter_token => oauth.access_token.token, 
      :twitter_secret => oauth.access_token.secret,
    })

    redirect_to root_path

推特请求令牌和密钥已经被成功设置。然而,我最终遇到了授权错误:

 OAuth::Unauthorized in MainController#twitter_callback

401 Unauthorized

RAILS_ROOT: /Users/TAmoyal/Desktop/RoR_Projects/mls
Application Trace | Framework Trace | Full Trace

/Library/Ruby/Gems/1.8/gems/oauth-0.3.4/lib/oauth/consumer.rb:167:in `token_request'
/Library/Ruby/Gems/1.8/gems/oauth-0.3.4/lib/oauth/tokens/request_token.rb:14:in `get_access_token'
/Library/Ruby/Gems/1.8/gems/erwaller-twitter-0.6.13.1/lib/twitter/oauth.rb:29:in `authorize_from_request'
/Users/TAmoyal/Desktop/RoR_Projects/mls/app/controllers/main_controller.rb:70:in `twitter_callback'
代码在这一行出错:
oauth.authorize_from_request(session[:twitter_request_token], session[:twitter_request_secret])

当它尝试获取访问令牌时。您可以在此处查看authorize_from_request的源代码。我不确定为什么会发生这种情况。有人有想法吗?

8个回答

78

我来晚了,但我也遇到了同样的问题。我将问题追踪到Twitter中我的OAuth应用程序的设置上。一开始,由于不确定回调URL,我并没有指定回调URL。

当我设置好我的rails应用程序后,我返回Twitter,发现因为我没有指定回调URL,Twitter默认我是一个桌面应用程序。一旦我将其更改为网站并输入了回调URL,我就不再收到400错误了。


桌面应用和 Web 应用实际上有什么区别? - Radek
@Radek - 桌面和网络应用本质上是相同的。然而,桌面应用程序无法在授权过程中拥有回调URL。相反,Twitter会生成一个PIN码,然后显示给用户,用户将其输入到桌面应用程序中。 - Dan Diplo
@Dan Diplo:感谢您的解释。我仍然想知道回调URL是如何工作的。它是否始终是相同的URL,并且所有信息都仅存储在标头中? - Radek
@Radek - 当你在Twitter上注册应用程序时,你需要注册回调URL。但是,在认证请求中,你也可以指定回调URL,这将覆盖之前的设置并允许其动态变化。所有信息都被传递为标头,但是由消费者应用程序存储最终令牌和密钥。请参阅http://dev.twitter.com/pages/auth。 - Dan Diplo
2
让我困惑的是:虽然你可以在请求中覆盖回调URL,但如果你在Twitter注册应用程序时没有输入 something 作为回调URL,那么Twitter会将你的设置默认为“客户端应用程序”。除非你再次进入编辑设置,否则你不会注意到这一点。 - tardate
通过将“http://127.0.0.1:3000/auth/twitter/callback”设置为本地测试的回调URL,对我很有效。 - sunsations

30

1
谢谢,这对我有用。回调URL:http://127.0.0.1:3000/auth/twitter/callback。 - Pankaj
3
请注意,您需要使用 127.0.0.1 格式,因为 Twitter 不接受本地主机。 - user2398029
这对我起了作用 https://dev59.com/DV3Va4cB1Zd3GeqPCJ1H?rq=1 - Keon

8

Twitter不允许将localhost作为有效回调URL的一部分。

请改用http://127.0.0.1:3000/auth/twitter/callback

希望这可以帮到您。


8

这是关于您的系统与Twitter服务器进行时间同步的问题。


2
如果您的服务器时间偏差很大(例如,虚拟机时钟已经跑偏),那么您将会收到一个“Twitter OAuth 401未经授权”的错误(例如,如果您正在使用OAuth gem)。更改时间可以解决此问题。 - RidingTheRails
非常感谢!这真的让我很烦恼。我检查了一下,发现我的VMWare Fusion虚拟机没有设置与主机同步时间。在高级设置中勾选同步时间选项后,它立即开始工作了。 - David

4
这是我遇到过的最烦人的调试问题之一。由于URL是动态的,并且在我的测试用例中没有定义(我使用它来显示图表数据,但现在还不够,因此Google Chart API的URL为空),所以我无意中在几个地方输出了 <img> 标签。这导致我的浏览器在加载某些页面时向本地主机发出多次请求。不知何故,这使得OAuth过程失效了。显然,S.O.上的人们无法了解我的应用程序特定的问题,因此我不得不自己回答这个问题。

你能详细说明一下吗?是指多个请求,例如重定向吗?还是在同一个请求中包含图像/静态文件? - Kyle
已经有一段时间了,但我认为这个想法是,如果你有一个带有空源(src =“”)的img标签,或者可能是(src =“/”),你的浏览器会尝试重新加载你的网站以获取图像。因此,对于每个空源图像,您都会获得额外的加载。 - Tony
谢谢Tony,你真是救星。你知道这会导致OAuth出问题的原因吗? - meow
老实说,我已经记不起来为什么了。很高兴这有所帮助。 - Tony

2

我曾经遇到同样的问题,但是这个主题中提出的建议都没有对我有用。

后来我发现问题出在我的请求时间戳上。我运行脚本的移动设备时钟不准确。当我将设备系统时间更新为正确的时间(即现在),所有请求都返回“200 OK”,而不是“401未经授权”。


太高兴你留下了这个解决方案。我在 MacBook Air 上也遇到了同样的问题,时钟不准确。如果没有你的帮助,我可能会浪费很多时间走弯路——非常感谢 Kenny! - jmejia

1

这个问题似乎是由于 Twitter 无法正确处理 connection keep-alive 导致的。请确保在向 Twitter 发送请求时设置 connection=close http header。我浪费了一个周末来调试这个问题。


你能解释一下你是如何实现这个的吗?你是用 OP 标记的其中一个 gem 来设置的吗?还是采用了不同的方法? - Christian Fazzini

0

信息不足,但 Twitter Gem 最后一次更新是什么时候?Twitter 在 5 月中旬左右更改了他们的 OAuth “东西”。也许你使用的是旧版本。我建议更新你的问题并显示回调 URL,并确保你拥有正确的令牌和密钥,看起来你没有它们。

另外,你是否在 Twitter 应用程序页面中添加了正确的回调 URL?很多时候这也会导致错误。

如果以上方法都失败了,可以试试 mbleighs 的 twitter_auth,它对我很有效且相当顺畅。


我已将我的回调URL添加到示例中。我知道人们现在正在成功使用Twitter gem,但是使用oauth 0.3.4(0.3.5破坏了一些东西)。至于正确的令牌和密钥,我直接从我的Twitter应用程序设置中复制了消费者密钥和密钥...不确定这些如何出错。请求令牌和密钥只生成一次并保存在会话中,因此它们不会更改,我也不确定它们可能出错。你所说的“正确的回调URL”是什么意思?我肯定被重定向到我的Web应用程序中的正确操作...这不意味着它是正确的吗? - Tony

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接