You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Twitter API分片上传INIT请求认证失败(错误码32)求助

问题诊断与修复方案

核心原因:OAuth1签名基字符串参数未按字典序排序

Twitter的OAuth1认证要求所有参与签名的参数(包括请求体中的非OAuth参数)必须按参数名的ASCII升序排列,这是触发code:32认证错误的关键原因。你的代码构造签名基字符串时参数顺序不符合规范,导致签名验证失败。此外还有两处编码一致性问题需要修正。

具体问题点

  1. 签名参数顺序错误:当前baseFormat_pic中的参数未按字典序排列,正确顺序需严格遵循参数名首字母的ASCII升序。
  2. 参数编码不一致:构造签名基字符串时,total_bytes未做URL编码;media_type的编码逻辑需和请求体保持统一。
  3. 哈希编码格式错误:生成签名哈希时使用ASCII编码,可能引发潜在字符编码问题,应改用UTF-8。

修复后的代码片段

// 1. 按字典序排列所有参与签名的参数
var baseFormat_pic = "command={0}&media_type={1}&oauth_consumer_key={2}&oauth_nonce={3}&oauth_signature_method={4}&oauth_timestamp={5}&oauth_token={6}&oauth_version={7}&total_bytes={8}";
var encodedMediaType = HttpUtility.UrlEncode("video/mp4");
var encodedTotalBytes = HttpUtility.UrlEncode(fileBytes.ToString());
var baseString_pic = string.Format(baseFormat_pic,
                     HttpUtility.UrlEncode("INIT"),
                     encodedMediaType,
                     HttpUtility.UrlEncode(oauth_consumer_key),
                     HttpUtility.UrlEncode(oauth_nonce),
                     HttpUtility.UrlEncode(oauth_signature_method),
                     HttpUtility.UrlEncode(oauth_timestamp),
                     HttpUtility.UrlEncode(oauth_token),
                     HttpUtility.UrlEncode(oauth_version),
                     encodedTotalBytes);

// 2. 拼接并编码签名基字符串
baseString_pic = string.Concat("POST&", Uri.EscapeDataString(resource_url_pic),
                               "&", Uri.EscapeDataString(baseString_pic));
var compositeKey_pic = string.Concat(Uri.EscapeDataString(oauth_consumer_secret),
                                  "&", Uri.EscapeDataString(oauth_token_secret));

string oauth_signature_pic;
// 3. 使用UTF-8编码生成哈希
using (HMACSHA1 hasher = new HMACSHA1(Encoding.UTF8.GetBytes(compositeKey_pic)))
{
    oauth_signature_pic = Convert.ToBase64String(hasher.ComputeHash(Encoding.UTF8.GetBytes(baseString_pic)));
}

// 授权头构造逻辑保持不变(头内参数顺序不影响签名验证)
var headerFormat_pic = "OAuth oauth_consumer_key=\"{3}\", oauth_token=\"{4}\", oauth_signature_method=\"{1}\", oauth_timestamp=\"{2}\", oauth_nonce=\"{0}\", oauth_version=\"{6}\", oauth_signature=\"{5}\"";

var authHeader_pic = string.Format(headerFormat_pic,
                                   Uri.EscapeDataString(oauth_nonce),
                                   Uri.EscapeDataString(oauth_signature_method),
                                   Uri.EscapeDataString(oauth_timestamp),
                                   Uri.EscapeDataString(oauth_consumer_key),
                                   Uri.EscapeDataString(oauth_token),
                                   Uri.EscapeDataString(oauth_signature_pic),
                                   Uri.EscapeDataString(oauth_version)
                                   );

ServicePointManager.Expect100Continue = false;
string reqUrl = resource_url_pic; 
HttpWebRequest request = (HttpWebRequest)WebRequest.Create(reqUrl);
request.Method = "POST";

// 请求体保持编码一致性
NameValueCollection nvc = new NameValueCollection();
nvc.Add("command", "INIT");
nvc.Add("total_bytes", fileBytes.ToString());
nvc.Add("media_type", "video/mp4");

var sb = new StringBuilder();
foreach (string key in nvc.Keys)
{
     sb.AppendFormat("{0}={1}&", key, HttpUtility.UrlEncode(nvc[key].ToString()));
}
sb.Remove(sb.Length - 1, 1);

var bytes = Encoding.UTF8.GetBytes(sb.ToString());
request.ContentLength = bytes.Length;
request.Headers.Add("Authorization", authHeader_pic);
request.ContentType = "application/x-www-form-urlencoded;charset=UTF-8";
using (var stream = request.GetRequestStream())
{
    stream.Write(bytes, 0, bytes.Length);
}
string result = ReadResult(request);

额外注意事项

  • 确保oauth_nonce每次请求生成唯一值,避免重复使用导致认证失败。
  • 确认resource_url_pic为https://upload.twitter.com/1.1/media/upload.json,且未附加任何查询参数(若有查询参数需一并纳入签名逻辑)。
  • total_bytes必须是视频文件的准确字节数,不能存在格式错误。

内容的提问来源于stack exchange,提问作者DorrisDormouse

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.07 22:00:23