创建签名

本页面介绍如何为 HTTP 请求生成 OAuth 1.0a HMAC-SHA1 签名。该签名将适合随附授权请求一并传递给 Twitter API,如授权请求中所述。

用于演示签名的请求是一个指向 https://api.twitter.com/1.1/statuses/update.jsonPOST。原始请求如下所示:

POST /1.1/statuses/update.json?include_entities=true HTTP/1.1
Accept: */*
Connection: close
User-Agent:OAuth gem v0.4.4
Content-Type: application/x-www-form-urlencoded
Content-Length:76
Host: api.twitter.com

status=Hello%20Ladies%20%2b%20Gentlemen%2c%20a%20signed%20OAuth%20request%21

收集请求方法和 URL

若要生成签名,请先确定请求的 HTTP 方法和 URL。可在创建请求时知道这两项信息,因此它们很容易获取。

对于 Twitter API 请求,请求方法几乎总是 GETPOST

HTTP 方法 POST

基址 URL 是将请求定向到的 URL,其中删除了任何查询字符串或哈希参数。在这里使用正确的协议很重要,所以请确保 URL 的“https://”部分与发送到 API 的实际请求相匹配。

基址 URL https://api.twitter.com/1.1/statuses/update.json


收集参数

接下来,收集请求中包含的所有参数。对于这些附加参数,存在两个这样的位置 - URL 和请求正文;其中 URL 是查询字符串的一部分。示例请求在这两个位置包含单个参数:

POST /1.1/statuses/update.json?include_entities=true HTTP/1.1
Accept: */*
Connection: close
User-Agent:OAuth gem v0.4.4
Content-Type: application/x-www-form-urlencoded
Content-Length:76
Host: api.twitter.com

status=Hello%20Ladies%20%2b%20Gentlemen%2c%20a%20signed%20OAuth%20request%21

HTTP 请求有一些 URL 编码的参数,但你应该收集原始值。除了请求参数,每个 oauth_* 参数也需要包含在签名中,因此也要收集这些参数。以下是对请求授权中的参数:

参数 示例值
status Hello Ladies + Gentlemen, a signed OAuth request!
include_entities true
oauth_consumer_key xvz1evFS4wEEPTGEFPHBog
oauth_nonce kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg
oauth_signature_method HMAC-SHA1
oauth_timestamp 1318622958
oauth_token 370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb
oauth_version 1.0


需要将这些值编码到一个字符串中,稍后将用到。构建字符串的过程非常具体:

  1. 对要签名的每个密钥和值进行百分比编码
  2. 按已编码的密钥 [2] 根据字母顺序对参数列表进行排序 [1]
  3. 对于每个密钥/值对:
  4. 将已编码的密钥附加到输出字符串。
  5. 将“=”字符附加到输出字符串。
  6. 将已编码的值附加到输出字符串。
  7. 如果还有更多的密钥/值对,则将“&”字符附加到输出字符串。
     

[1] OAuth 规范要求按字典排序,这是很多库的默认字母排序方式。

[2] 如果有两个参数具有相同的编码密钥,OAuth 规范要求继续根据值进行排序。不过,Twitter 不接受 API 请求中的重复密钥
 

参数字符串

使用上面收集的参数重复这些步骤,生成以下参数字符串

include_entities=true&oauth_consumer_key=xvz1evFS4wEEPTGEFPHBog&oauth_nonce=kYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1318622958&oauth_token=370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb&oauth_version=1.0&status=Hello%20Ladies%20%2B%20Gentlemen%2C%20a%20signed%20OAuth%20request%21

 

创建签名基本字符串

迄今为止收集到的三个值必须连接成一个字符串,系统将基于该字符串生成签名。这在 OAuth 规范中被称为签名基本字符串

若要将 HTTP 方法、基址 URL 和参数字符串编码到一个字符串中:

  1. 将 HTTP 方法转换为大写字母,并将输出字符串设置为等于此值。
  2. 将“&”字符附加到输出字符串。
  3. 对 URL 进行百分比编码,并将其附加到输出字符串。
  4. 将“&”字符附加到输出字符串。
  5. 对参数字符串进行百分比编码,并将其附加到输出字符串。
     

这会生成以下签名基本字符串

POST&https%3A%2F%2Fapi.twitter.com%2F1.1%2Fstatuses%2Fupdate.json&include_entities%3Dtrue%26oauth_consumer_key%3Dxvz1evFS4wEEPTGEFPHBog%26oauth_nonce%3DkYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1318622958%26oauth_token%3D370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb%26oauth_version%3D1.0%26status%3DHello%2520Ladies%2520%252B%2520Gentlemen%252C%2520a%2520signed%2520OAuth%2520request%2521

 

确保对参数字符串进行百分比编码。签名基本字符串应恰好包含 2 个与号“&”字符。参数字符串中的百分比“%”字符应在签名基本字符串中编码为 %25
 

获取签名密钥

最后要收集的数据是机密,它用于识别发出请求的 Twitter 应用,以及请求所代表的用户。需要注意的是,这些值非常敏感,绝对不得与任何人分享。

识别应用是 Twitter 的值被称为使用者机密,并可在开发者门户中查看应用详细信息页找到。对于你的 Twitter 应用发送的每个请求来说,该值将是相同的。

使用者机密 kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw

识别你的应用程序所代表的账号的值被称为 OAuth 令牌机密。该值可通过几种方式获得,具体都请查看获取访问令牌

OAuth 令牌机密 LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE

再次强调,使这些值只有你的应用程序知道非常重要。如果你认为值遭到泄露,请重新生成令牌(本页中的令牌已被标记为对实际请求无效)。

需要将这两个值组合成一个签名密钥,它将用于生成签名。简单来说,签名密钥就是已进行百分比编码的使用者机密,后跟一个与号字符“&”,再后面是已进行百分比编码的令牌机密:

请注意,在有些流中(例如获取请求令牌时),令牌机密尚且未知。在这种情况下,签名密钥应该由已进行百分比编码使用者机密组成,后跟一个与号字符“&”。

签名密钥 kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw&LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE


计算签名

最后,将签名基本字符串和签名密钥传递到 HMAC-SHA1 哈希算法来计算签名。有关该算法的详细信息,可查看 hash_hmac 函数。

HMAC 签名函数的输出内容是一个二进制字符串。这需要用 base64 编码来生成签名字符串。例如,具有本页上给定的基本字符串和签名密钥的输出内容是 84 2B 52 99 88 7E 88 7602 12 A0 56 AC 4E C2 EE 16 26 B5 49。当转换为 base64 时,该值就是此请求的 OAuth 签名:

OAuth 签名 hCtSmYh+iHYCEqBWrE7C7hYmtUk=