创建签名

本页面介绍如何为 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=

 

Was this document helpful?

感谢

谢谢你的反馈。我们真的很高兴能帮上忙!

Thank you for the feedback. How could we improve this document?

Thank you for the feedback. Your comments will help us improve our documents in the future.