创建签名
本页面介绍如何为 HTTP 请求生成 OAuth 1.0a HMAC-SHA1 签名。该签名将适合随附授权请求一并传递给 Twitter API,如授权请求中所述。
用于演示签名的请求是一个指向 https://api.twitter.com/1.1/statuses/update.json 的 POST。原始请求如下所示:
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 请求,请求方法几乎总是 GET 或 POST。
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 |
需要将这些值编码到一个字符串中,稍后将用到。构建字符串的过程非常具体:
- 对要签名的每个密钥和值进行百分比编码。
- 按已编码的密钥 [2] 根据字母顺序对参数列表进行排序 [1]。
- 对于每个密钥/值对:
- 将已编码的密钥附加到输出字符串。
- 将“=”字符附加到输出字符串。
- 将已编码的值附加到输出字符串。
- 如果还有更多的密钥/值对,则将“&”字符附加到输出字符串。
[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 和参数字符串编码到一个字符串中:
- 将 HTTP 方法转换为大写字母,并将输出字符串设置为等于此值。
- 将“&”字符附加到输出字符串。
- 对 URL 进行百分比编码,并将其附加到输出字符串。
- 将“&”字符附加到输出字符串。
- 对参数字符串进行百分比编码,并将其附加到输出字符串。
这会生成以下签名基本字符串:
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= |