创建唯一参数时Twitter API授权返回401错误问题求助
错误原因与修复步骤
签名参数集合不匹配
你在Authorization请求头中包含了oauth_callback参数,但构造签名用的parameterString里没有加入该参数,OAuth 1.0a要求参与签名计算的参数必须和请求头里的OAuth参数、接口的所有查询参数完全一致,两者不匹配就会直接导致签名校验失败返回401。
你需要把oauth_callback的编码后的值加入到parameterString的参数列表中。参数串包含多余无效参数
你使用的是Twitter API v2的发推端点https://api.twitter.com/2/tweets,该端点不需要status、include_entities这两个v1.1版本的接口参数,这两个参数不存在于你的实际请求中,加入参数串会直接导致签名计算错误。
另外该端点请求体格式为JSON,OAuth 1.0a签名计算时不会将JSON请求体的内容纳入参数串,你只需要在参数串中保留OAuth相关参数即可,不需要加入任何请求体对应的参数。百分号编码不符合规范
JavaScript原生的encodeURIComponent不会对星号*、感叹号!、单引号'、括号()进行编码,但Twitter要求所有非字母数字的特殊字符都要做百分号编码,比如*需要编码为%2A,你需要自定义编码函数处理这部分差异。签名基础URL校验
确认你编码的encodedURL和实际请求的URL完全一致,不能有多余的斜杠、大小写不一致、多余的查询参数等问题,必须和请求地址完全匹配。
修正后的核心代码示例
// 自定义符合Twitter规范的编码函数 function encodeRFC3986(str) { return encodeURIComponent(str) .replace(/!/g, '%21') .replace(/'/g, '%27') .replace(/\(/g, '%28') .replace(/\)/g, '%29') .replace(/\*/g, '%2A'); } // 构造参与签名的参数,不要加多余的status、include_entities参数,加入oauth_callback const oauthParams = { oauth_consumer_key: CONSUMER_KEY, oauth_nonce: OAUTH_NONCE, oauth_signature_method: SIGNATURE_METHOD, oauth_timestamp: OAUTH_TIMESTAMP, oauth_token: ACCESS_TOKEN_KEY, oauth_version: '1.0', oauth_callback: 'https://127.0.0.1' } // 参数按key字典序排序后拼接成参数字符串 const sortedParams = Object.keys(oauthParams).sort().map(key => { return `${encodeRFC3986(key)}=${encodeRFC3986(oauthParams[key])` }).join('&') // 构造签名基础字符串,确保URL完全匹配 const encodedURL = encodeRFC3986('https://api.twitter.com/2/tweets') const encodedParameterString = encodeRFC3986(sortedParams) const signatureBaseString = `POST&${encodedURL}&${encodedParameterString}` // 构造签名密钥,密钥同样用自定义编码函数处理 const encodedConSecret = encodeRFC3986(CONSUMER_SECRET) const encodedOAuthSecret = encodeRFC3986(ACCESS_TOKEN_SECRET) const signingKey = `${encodedConSecret}&${encodedOAuthSecret}` // 哈希和签名生成逻辑不变 const hash = CryptoJS.HmacSHA1(signatureBaseString, signingKey) const OAUTH_SIGNATURE = encodeRFC3986(CryptoJS.enc.Base64.stringify(hash))
内容的提问来源于stack exchange,提问作者bitterFunk
相关产品推荐
相关产品推荐

