Meta
VILIC18:24 - 04.28 2011
腾讯微博API OAuth验证及微博发送 (JavaScript)( 15 responses )

首先, 道路是曲折的... 之前曾小试过 Basic 验证, 一开是也是不得要领, 不过悟透那个就显然快多了.

这是第一次做 OAuth 的验证, 在此实在想狠狠地骂腾讯的 API 说明文档, 不清不楚, 害得我到处查, 到处试... 总算, 经过一个上午的奋斗, 成功获取了 Request Token, 下午再稍加努力, 终于把 Access Token 拿到了手, 晚上又继续奋战, 搞定了微博发送, 至此, 也算对 OAuth 及腾讯微博的 API 有了个基本的了解.

JavaScript 实现腾讯微博的 OAuth 的难点在于 HMAC-SHA1 加密, 而且之后还得转换成 Base64, 最变态的是, 获取 Request Token 的时候, 加密时 AppKey 后面还得跟上个 "&"!!! 比如原来 AppKey 是 "123456", 那么加密时的 Key 就是 "123456&"

好吧, 既然大家在看这篇文章, 相信关于 XMLHttpRequest 这些也比较熟悉了, 我就说说重点 (因为我是第一次真正接触 OAuth, 所以对里面一些约定俗成的东西可能还不清楚, 所以高手看了不要笑我这些 "重点" 太幼稚).

HMAC-SHA1 加密的 JavaScript 实现

在网上搜这个搜了很久, 最后找到了一个叫 Crypto-JS 的东西, 一看, 果然是好家伙, 里面提供了非常丰富的加密方式, 值得收藏. http://code.google.com/p/crypto-js/ 下载后引用 crypto.js, sha1.js, hmac.js 三个文件, 加密方式如下:

var message = "Message to be encoded";
var secret = "Secret phrase";

var bytes = Crypto.HMAC(Crypto.SHA1, message, secret, { asBytes: true }) ;
//但仅仅这样还不行, 还得转换成Base64.
//在Crypto.util下找到相应的方法.
var signature = Crypto.util.bytesToBase64(bytes);

这样就搞定啦. 需要注意的是 (前面我也有提到), 在获取 Request Token 的时候, secret需要在 App Secret 后面加上 "&". 获取 Access Token 的时候, 则是用 "&" 把 App Secret 和 Token Secret连起来.

参数编码

按说这个是算不上重点的, 不过实在找不到东西写, 就把这个算上去吧.

方法很简单, 使用JavaScript内置的encodeURIComponent()方法即可.

看来这里还真是重点, 编码要求要什么 [RFC3986], 在 encodeURIComponent() 的基础上, 还要额外编码 ! * ( ) ' 这5个字符.

否则当添加微博的内容中出现这些字符的时候, oauth_signature 参数会有误, 导致鉴权失败.

时间戳

注意单位是哦! new Date().getTime()的单位是毫秒, 所以注意先除以1000再取整.

要签名的Base String

里面的参数要排序, 当然这个文档中也强调了. 另外就是这些参数中是不包括 oauth_signature 的. 显然, 也没法包含这个参数, 不过我这样点明下, 免得大家心生疑惑.

 

最后, 这个是我用 HTA (JavaScript) 实现的一个验证和发微博的小Demo, http://www.vilic.info/demo/vt.rar . 源码是基于 vejis 的, 如果有看不太明白的可以参考 vejis.js 文件中的说明. (补充, 后来发现有个小Bug, 其实不算Bug, 我一开始以为所有的API都可以用POST方法, 就全部使用的是POST, 对应的稍微小改就可以了)

Original link of this archive: http://www.vilic.info/blog/archives/659
本文的原始链接: http://www.vilic.info/blog/archives/659

There're 15 Comments to "腾讯微博API OAuth验证及微博发送 (JavaScript)"
  • Bruce11:26 - 04.29 2011
    强啊!
    Bruce
  • Melody18:06 - 04.30 2011
    来个纯文本微博推送。。
    Melody
  • Vilic20:51 - 04.30 2011
    @Melody 神马意思?
    Vilic
  • qian95111:06 - 07.07 2011
    var message 该填什么?我随便写的话无法通过验证
    qian951
  • VILIC14:38 - 07.07 2011
    @qian951 当然不能随便填啦, 这个就是那个需要加密的BaseString, 你看有介绍算法的.
    VILIC
  • qian95118:11 - 07.07 2011
    secret写错了我写了Consumer key应该为Consumer secret

    给博主添蘑菇了=.=前面的2楼删掉吧T.T
    qian951
  • VILIC10:07 - 07.09 2011
    @qian951 呵呵, 看来最后成功了呀, 恭喜~
    VILIC
  • m20818:05 - 12.06 2011
    用VB来写怎么就签名错误呢= =VB code看得懂吧,我有注释。
    '代码中的a是用于生成hmac-sha1签名的控件
    Dim url As String '定义请求参数变量开始
    Dim oauth_consumer_key As String
    Dim oauth_signature_method As String
    Dim oauth_signature As String
    Dim oauth_timestamp As String
    Dim oauth_nonce As String
    Dim oauth_callback As String
    Dim oauth_token As String
    Dim oauth_token_secret As String '定义请求参数变量结束
    a.EncodingMode = "string" '设置签名返回值类型
    a.HashAlgorithm = "sha-1" '设置hmac的类型
    a.SetHmacKeyString ("90e3acab1c88dee8df298e5612aaa8ab&") '设置加密用的key
    url = "https://open.t.qq.com/cgi-bin/request_token" '赋值变量开始
    oauth_consumer_key = "oauth_consumer_key=801063961&"
    oauth_signature_method = "oauth_signature_method=HMAC-SHA1&"
    N = 32
    For i = 1 To N 'N是指定长度
    Randomize
    T = Int(Rnd() * 3)
    Select Case T
    Case 0
    Randomize
    R = R & Chr(Int(Rnd() * 25) + 65) '生成一个大写字母
    Case 1
    Randomize
    R = R & Chr(Int(Rnd() * 25) + 97) '生成一个小写字母
    Case 2
    Randomize
    R = R & Chr(Int(Rnd() * 9) + 48) '生成一个数字
    End Select
    Next i
    oauth_nonce = "oauth_nonce=" & R & "&"
    oauth_callback = "oauth_callback=null&"
    oauth_timestamp = "oauth_timestamp=" & ToUnixTime(Now(), 8) '赋值变量结束
    oauth_signature = "oauth_signature=" & a.HmacStringENC("GET&" & URLEncode(url) & "&" & URLEncode(oauth_callback & oauth_consumer_key & oauth_nonce & oauth_signature_method & oauth_timestamp)) & "&" '生成签名
    ' 然后通过XMLHTTP请求,总是签名错误,用web调试工具提示说签名不正确,根据所提交的参数和密钥,签名应该为(此处省略签名)
    m208
  • VILIC16:40 - 12.07 2011
    @m208 囧, 中间貌似很多细节问题啊, 比如最后生成的签名要先Base64编码再URLEncode什么的, 你再好好看下OAuth的文档吧.
    VILIC
  • m20819:12 - 12.09 2011
    那个控件的方法生成后就是有base64编码的。。。我密钥也有在后面加&的啊= =
    m208
  • VILIC18:12 - 12.10 2011
    @m208 咦, 我怎么没看到你算签名的时候有传进去密钥做参数?
    VILIC
  • m20811:43 - 12.16 2011
    @VILIC a.SetHmacKeyString ("90e3acab1c88dee8df298e5612aaa8ab&") '设置加密用的key 难道你没看到吗= =
    m208
  • VILIC20:51 - 12.17 2011
    @m208 囧... 没注意到前面的... 我记得Qzone的OAuth验证给了实例, 你照着一步一步对, 看看是哪里的问题? 这个我自己写的代码都要折腾很久的.
    VILIC
  • m20821:38 - 12.17 2011
    @VILIC qzone的是oauth2.0,微博的是1.0,是有区别的= =
    m208
  • VILIC16:35 - 12.18 2011
    @m208 囧... 当年我看的时候它还是1.0的... 哎... 老了.
    VILIC
Leave a Comment