OAuth 认证步骤

38 条评论

Twitter 将于本月16日开始限制 Basic authentication 的使用,而直至本月31日,所有 Basic authentication 的请求都将只能收到 403 的回复了。尽管这会给亚洲某个地区的用户带来很大的不便,但是我们也要看到 OAuth 的好处,比如更强的安全性,因为不会泄漏用户的密码等信息,脱离密码的另一个好处就是各种应用可以无视用户对密码的修改,用户修改密码后并不会影响应用的正常工作,此外,我们可以给自己的消息设置一个自定义来源名称,利于个性化...

这两天我尽力地先改进自己的微博客同步工具,以便支持 OAuth 认证,失败了无数次,积累了一些经验,分享一下。

Authenticating Requests with OAuth 这篇官方的指导是必须要看的,事实上如果仔细地阅读了这篇文章,那么也不会出现什么问题了。不过我再画蛇添足地说一下具体的过程吧-.-

一、创建应用

当我们在 Twitter applications 页面创建了一个应用之后(假设为客户端的,以下也以此为例了),我们可以获得如下的信息:Consumer key ,Consumer secret ,Request token URL ,Access token URL ,Authorize URL 这些东西拿来干什么的,怎么用呢?我们继续...

二、获取未授权的 Request Token

当然不是一笔带过地说一句“把Consumer key 和 Consumer secret 放入 HTTP 请求中发送到 Twitter API ”就完了,我不知道有多少人看到这样一句话的时候是跟我一样的完全摸不着头脑,放入请求是要怎么个放法...?

在获取 Request Token 的时候,我们需要

  • oauth_consumer_key, 就是我们在创建应用时的 Consumer key
  • oauth_signature_method,Twitter 支持 HMAC-SHA1
  • oauth_timestamp,就是当前时间距 1970 00:00:00 GMT 的秒数,注意必须为整数值
  • oauth_nonce,每次自己随机生成的字符串,能保证每次的都不同就好了
  • oauth_version,现在为 1.0
  • oauth_callback,使用客户端的时候可以空着 oauth_callback,twitter能懂的~
  • oauth_signature,这个是最复杂的,下一段解释-.-

在获取 oauth_signature 之前我们要先得到一个叫做 base string 的东西,它由 HTTP 方法名(一般可以选择 GET 或者 POST,我说..我们这里用 GET)、URL 编码的请求路径(urlencode之后的 Request token URL)和请求的参数表(除了 oauth_signature 之外的所有参数按照名称经过重新排序之后使用&号连接,最后 urlencode)组成。这样我们就可以得到一个类似这样的 base string 了
GET&https%3A%2F%2Fapi.twitter.com%2Foauth%2Frequest_token&oauth_consumer_key%3DGDdmIQH6jhtmLUypg82g%26oauth_nonce%3DQP70eNmVz8jvdPevU3oJD2AfF7R7odC2XJcn4XlZJqk%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1272323042%26oauth_version%3D1.0

得到 base string 之后我们还需要一个 签名 key ,它就是由我们在创建程序时获得的 Consumer secret 和 oauth_token_secret 用 & 连接而成,不过我们在请求 Request Token 的时候还没有 oauth_token_secret 呀,那就 oauth_token_secret 为空,不过中间的 & 不能省。

在获得 base string 和 signing key 之后就可以利用这两者来生成 oauth_signature了,比如python的实现 

base64.b64encode(hmac.new(consumer_secret+'&', base_string, hashlib.sha1).digest())

注意:在使用 GET 方式传送时,oauth_signature 不需要再进行 urlencode 了,但是在使用 POST 方式,将所有参数放在 header 里的时候,oauth_signature 还需要再进行一次 urlencode 。

好了,现在我们获取未授权 Request Token 时需要的参数都齐备了,连接到创建程序时获得的 Request token URL 之后(中间加?),得到类似这样一个地址

https://api.twitter.com/oauth/request_token?oauth_nonce=5151577474&oauth_timestamp=1281769547&oauth_consumer_key=your_consumer_key&oauth_signature_method=HMAC-SHA1&oauth_version=1.0&oauth_signature=vdmXR5%2BZg5WHgFrC25vTZm4TfRg%3D

那么现在就用 GET 方式请求这个地址吧,返回的结果类似

oauth_token=xxxxx&oauth_token_secret=xxxxx&oauth_callback_confirmed=true

很轻松地就可以提取出来 request_token 和 request_token_secret 吧,不过此时的 Request Token 还是未授权的

三、用户授权此 Request Token

需要用户用浏览器打开这样一个地址:https://api.twitter.com/oauth/authorize?oauth_token=xxxxx ,当然其实最好是程序自动地帮用户打开了..-.-,很显然,前面一段呢就是用户在创建程序时获得的 Authorize URL ,中间加上 ?后面则是跟的上一步中获取到的 request_token ,好了,现在如果用户已经登陆了 twitter 的话,就可以看到这样一个界面了

OAuth authentication steps

点击 Allow 后完成授权,此时会出现一串 PIN 码,用户应该记下来,以便接下来再获取 Access token

四、获取 Access token

总结一下,我们通过以上几步新获得了几个参数,授权过的 request_token 和 request_token_secret,还有一个 PIN 码。

获取 Access token 的过程和获取未授权的 Request token 过程是类似的,所以我这里只介绍一下其中仅有的几点区别,获取 Access token 时和 Request token不同的是需要 8 个参数,去掉 oauth_callback 这个,但是另外加上 oauth_verifier (值就是上面的 PIN 码)和 oauth_token (值就是刚获得的 request_token),另外 signing key 里的 oauth_token_secret 不再为空了,它就是刚才获得的 request_token_secret ,最后一点就是请求的地址前面部分为创建程序时获得的 Access token URL ,其他的规则都是一样的,当然最后获得的放回结果里就是 access_token 和 access_token_secret 了,对于 access_token 和 access_token_secret 我们可以保存下来,以后访问受保护的资源则直接利用它,而不需要每一次都经历一下上面的曲折阶段。

五、拿到 Access token 来发一条消息

和获取 Access token 相比,进行资源访问等操作时所需的参数不包含 oauth_verifier,而外添加一个 status 的参数(准确点应该是 POST 内容的主体部分),其值为发送的消息(UTF-8编码不解释) 其他参数则都是一样的( oauth_token 为 access_token),oauth_signature 的生成当然也还是一样需要 signing key (由 consumer_key 和 access_token_secret组成)和 base string (请求地址为 API 地址),不过这一次必须要使用 POST 方式提交数据,所以在生成 base string 时的方法为 POST,最终生成的 oauth_signature 也需要 urlencode。

这一次,所有的参数不再需要跟某个地址进行连接操作了,我们构造一个 HTTP Authorization header ,结果如下

OAuth status="%E4%B8%80%E5%A0%86%E5%BE%AE%E5%8D%9A%E5%AE%A2",oauth_nonce="4992019565",oauth_timestamp="1281772029",oauth_consumer_key="your_consumer_key",oauth_signature_method="HMAC-SHA1",oauth_version="1.0",oauth_token="your_access_token",oauth_signature="dFmXo%2BxOWFMOhkZWTl80fh3IelM%3D"

可见就是"OAuth "之后将所有的参数列了出来,这样在使用 POST 方式请求 API 的时候带上这样一个 Authorization header ,同时 POST 的内容为 status=message (不要忘记 urlencode),便能成功地发布一条消息了。

相关日志 Relate Posts

收藏与分享 : Twitter | Facebook | 微博 | 人人 | Google+ | PDF

“OAuth 认证步骤”38条留言

  1. 我看不懂我自重 💡

  2. 是的,水水大多就跳过,直接给一个已阅之类的 😀

    • @littlewater 是说文章内容么 ➡

    • 反正专心也看不懂- -|||

    • @littlewater -.- 好吧,长一点的大家都不想看 🙁

    • 摸摸,不要太失望~

      当需要的时候,还嫌你写得太少了-x- 人类嘛~~

    • @littlewater “人类嘛” 😐

  3. 不懂……

  4. 靠…同沙发…PS:你这个网址后面有参数的话评论会到404…

    • @dning1 比如什么参数?

  5. 比如“comment-page-1#comment-2155”这种

    • @dning1 你是怎么得到这样一个地址的…?我控制评论不分页的…

  6. Br.st也会失效不,我那个代理注册的网站就没了,害博客还一直在请求

    • @Nic 看会不会被墙了

  7. 写的太好了,我对照官方资料看得。另外请问博主一个问题:我如何利用oauth做更多的操作,比如follow,reply,DM什么的。

    • @leekic 和发消息类似的吧,twitter在header里可能都需要有postbody

  8. 不知博主本人有没有用过Thread Twitter插件,这款插件似乎只能通过Basic认证才能登录,要是有人能让它支持Oauth认证就好啦。

    • @Gian 这个最好是联系作者叻- –

  9. 😉 完全看不懂。。。

    • @aiioef 就不要懂他叻

  10. 真的好详细 但还是希望你能把Access token 那部分展开来讲。你讲的是适用于C/S结构的。不知道和B/S有啥区别呀?

    • @会跳舞的鞋子 区别不大了,除了中间不是手动地输入pin码而是从callback里自己去提取。access token部分和上面的并没有多大区别,就不多废话了。

  11. 有没有QQ登陆的那个插件?

  12. 💡 如何获得已授权的Request Token和Request Token Secret !在使用授权后的Request Token换取Access Token的时候,总是会出现”远程服务器返回错误: (400) 错误的请求”,杯具死

  13. 我只想问一下,oauth是如何进行排序的啊,按照什么方法进行的排序

  14. 方不方便qq联系呢?290601953

  15. 😛 谢谢作者的仔细整理,虽然按你说的不能马上实现功能,但又很好的参考价值。

  16. 楼主你好,我看了以后明白了很多,但还有些细节不是很清楚,搞了很长时间都没得到最后的access_token 和 access_token_secret ,很是郁闷啊。那些参数是不是注册应用后可以在应用的界面生成啊?我拿生成的参数去操作总提示fail to valiad the token,哪位高手指导一下?万分感激! 🙂

  17. 写的很好啊 灰常感谢分享 🙂

  18. 正在学习啊

  19. 🙂 很好很强大,我再琢磨琢磨

    • -.- 似乎现在都是用OAuth 2.0 了?

  20. 请教一个问题…方便QQ联系吗?

  21. QQ295193696

  22. 请问最后在发送推文的时候报错“message”:”Could not authenticate you”,”code”:32”,全面一切正常,最后一部报错!求帮忙

发表留言(Ctrl+Enter提交)