跳转到主要内容

创建签名

本页介绍如何为 HTTP 请求生成 OAuth 1.0a HMAC-SHA1 签名。该签名可按授权请求中的说明,作为已授权请求的一部分传递给 X API。 用于演示签名的请求是向 https://api.x.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.x.com

status=Hello%20Ladies%20%2b%20Gentlemen%2c%20a%20signed%20OAuth%20request%21
收集请求方法和 URL 要生成签名,请先确定请求的 HTTP 方法和 URL。这两项在创建请求时就已确定,因此易于获取。 对于 X API,请求方法几乎总是 GET 或 POST。
HTTP MethodPOST
基础 URL 指的是请求所指向的 URL,不包含任何查询字符串或哈希参数。务必使用正确的协议,确保 URL 中的“https://”部分与实际发送到 API 的请求一致。

收集参数

接下来,汇总请求中包含的所有参数。附加参数可能出现在两个位置: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.x.com

status=Hello%20Ladies%20%2b%20Gentlemen%2c%20a%20signed%20OAuth%20request%21
一个 HTTP 请求包含经过 URL 编码的参数,但你应收集其原始值。除了请求参数外,每个 oauth_* 参数也必须包含在签名中,因此一并收集。以下是来自授权请求的参数:
statusHello Ladies + Gentlemen, a signed OAuth request!
include_entitiestrue
oauth_consumer_keyxvz1evFS4wEEPTGEFPHBog
oauth_noncekYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg
oauth_signature_methodHMAC-SHA1
oauth_timestamp1318622958
oauth_token370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb
oauth_version1.0
这些值需要被编码为一个单独的字符串,稍后会用到。构建该字符串的过程非常具体:
  1. 对将要签名的每个键和值进行百分号编码
  2. 按编码后的键的字母顺序对参数列表排序[1] [2]
  3. 对于每个键/值对:
  4. 将编码后的键追加到输出字符串。
  5. 将“=”字符追加到输出字符串。
  6. 将编码后的值追加到输出字符串。
  7. 如果还剩更多键/值对,则将“&”字符追加到输出字符串。  
[1] OAuth 规范要求按字典序排序,这也是许多库的默认字母排序方式。 [2] 如果两个参数具有相同的编码键,OAuth 规范要求继续按值排序。不过,X 不接受在 API 请求中出现重复键   参数字符串 通过对上面收集的参数重复这些步骤,将生成以下参数字符串:
statusHello Ladies + Gentlemen, a signed OAuth request!
include_entitiestrue
oauth_consumer_keyxvz1evFS4wEEPTGEFPHBog
oauth_noncekYjzVBB8Y0ZFabxSWbWovY3uYSQ2pTgmZeNu2VS4cg
oauth_signature_methodHMAC-SHA1
oauth_timestamp1318622958
oauth_token370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb
oauth_version1.0

创建签名基字符串

到目前为止收集的三个值必须拼接为一个字符串,用于生成签名。OAuth 规范将其称为签名基字符串 要将 HTTP 方法、基准 URL 和参数字符串编码为一个字符串:
  1. 将 HTTP 方法转换为大写,并将输出字符串设为该值。
  2. 在输出字符串后追加‘&’字符。
  3. 百分编码该 URL,并将其追加到输出字符串。
  4. 在输出字符串后追加‘&’字符。
  5. 百分编码参数字符串,并将其追加到输出字符串。  
这将生成如下签名基字符串
POST&https%3A%2F%2Fapi.x.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。

获取签名密钥

最后需要收集的是用于标识发起请求的 X 应用 (/zh/resources/fundamentals/developer-apps) 以及该请求所代表用户的机密信息。请务必注意,这些值极其敏感,绝不应与任何人共享。 用于在 X 上标识你的应用的值称为 consumer secret,可在 开发者门户 (/zh/resources/fundamentals/developer-portal) 的 应用详情页面 (/zh/resources/fundamentals/developer-apps) 查看。对于你的 X 应用发送的每个请求,该值都相同。
Consumer secretkAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw
用于标识你的应用所代表账户的值称为 OAuth token secret。该值可通过多种方式获取,详见 获取访问令牌 (/zh/resources/fundamentals/authentication/oauth-1-0a/obtaining-user-access-tokens)。
OAuth token secretLswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE
再次强调,务必将这些值仅保存在你的应用内部。如果你认为这些值已泄露,请重新生成令牌(本页中的令牌已被标记为对真实请求无效)。 需要将上述两个值组合形成用于生成签名的 signing key。签名密钥即为对令牌密钥进行百分号编码 (/zh/resources/fundamentals/authentication/oauth-1-0a/percent-encoding-parameters)后的结果: 请注意,在某些流程中(例如获取 request token (/zh/resources/fundamentals/authentication/oauth-1-0a/obtaining-user-access-tokens) 时),令牌密钥尚未知晓。在这种情况下,签名密钥应由百分号编码 (/zh/resources/fundamentals/authentication/oauth-1-0a/percent-encoding-parameters)后的 consumer secret 后接一个与号字符 ’&’ 组成。
Signing keykAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw&LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE

计算签名

最后,将签名基字符串和签名密钥传递给 HMAC-SHA1 哈希算法来计算签名。有关该算法的详细说明,请参阅 hash_hmac 函数。 HMAC 签名函数的输出是一个二进制字符串。需要对其进行 base64 编码以生成签名字符串。例如,在本页给定的基字符串和签名密钥下,输出为 2E CF 77 84 98 99 6D 0D DA 90 5D C7 17 7C 75 07 3F 3F CD 4E。该值转换为 base64 后,即为此请求的 OAuth 签名:
OAuth 签名Ls93hJiZbQ3akF3HF3x1Bz8/zU4=