twitter api "update/status" returns 401 当我在查询字符串参数中发送逗号时
twitter api "update/status" returns 401 when i send a comma inside query string parameters
我想在 C#、.Net Core 3.1 中使用 Twitter api 发送 post。
我可以通过 OAuth 1.0 身份验证成功使用 "update/status" 推特 api 发送 post。但是当我在查询字符串中写逗号时,api returns 401.
- https://api.twitter.com/1.1/statuses/update.json?status=test1 测试 2
- https://api.twitter.com/1.1/statuses/update.json?status=test1, test2
例如,第一个请求运行成功但第二个请求运行失败。唯一的区别是逗号。我正在使用 Uri.EscapeDataString()。但它不起作用。我错过了什么?请帮我。谢谢。
public class OAuth1Manager : IOAuth1Service
{
private OAuth1Request _request;
private List<string> _requestParameters;
private List<string> _signatureParameters;
public List<string> GetQueryStrings(string url)
{
var splitted = url.Split("?");
if (splitted.Length > 1)
{
return splitted[1].Split("&").ToList();
}
return new string[0].ToList();
}
public string GetSignedOAuthString(OAuth1Request request)
{
_request = request;
_requestParameters = new List<string>
{
$"oauth_consumer_key={_request.OAuth.ConsumerKey}",
$"oauth_signature_method=HMAC-SHA1",
$"oauth_timestamp={GetTimeStamp()}",
$"oauth_nonce={GetNonce()}",
$"oauth_token={request.OAuth.AccessToken}",
$"oauth_version=1.0",
};
_signatureParameters = new List<string>();
_signatureParameters.AddRange(_requestParameters);
_signatureParameters.AddRange(GetQueryStrings(_request.Url));
_requestParameters.Add($"oauth_signature={GetSignature()}");
for (int i = 0; i < _requestParameters.Count; i++)
{
var parameter = _requestParameters[i];
var splitted = parameter.Split("=");
_requestParameters[i] = $"{splitted[0]}=\"{splitted[1]}\"";
}
return $"OAuth {_requestParameters.JoinAsString(",")}";
}
private string GetNonce()
{
var rand = new Random();
var nonce = rand.Next(1000000000);
return nonce.ToString();
}
private string GetSignatureBaseString()
{
var sortedList = new List<string>(_signatureParameters);
sortedList.Sort();
var requestParametersSortedString = sortedList.JoinAsString("&");
var url = ConstructRequestUrl();
return _request.Method.GetEnumDescription().ToUpper() + "&" + Uri.EscapeDataString(url) + "&" +
Uri.EscapeDataString(requestParametersSortedString);
}
private string ConstructRequestUrl()
{
var uri = new Uri(_request.Url, UriKind.Absolute);
var normUrl = string.Format("{0}://{1}", uri.Scheme, uri.Host);
if (!(uri.Scheme == "http" && uri.Port == 80 ||
uri.Scheme == "https" && uri.Port == 443))
normUrl += ":" + uri.Port;
normUrl += uri.AbsolutePath;
return normUrl;
}
private string GetSignature()
{
var hmacsha1 = new HMACSHA1();
var key = Uri.EscapeDataString(_request.OAuth.ConsumerSecret) + "&" + (string.IsNullOrEmpty(_request.OAuth.TokenSecret)
? ""
: Uri.EscapeDataString(_request.OAuth.TokenSecret));
hmacsha1.Key = Encoding.ASCII.GetBytes(key);
var dataBuffer = Encoding.ASCII.GetBytes(GetSignatureBaseString());
var hashBytes = hmacsha1.ComputeHash(dataBuffer);
return Uri.EscapeDataString(Convert.ToBase64String(hashBytes));
}
private string GetTimeStamp()
{
var ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();
}
}
我用 %2C 替换了所有逗号,例如 "test1%2Ctest2" 而不是 "test1,test2" 然后它起作用了。
我想在 C#、.Net Core 3.1 中使用 Twitter api 发送 post。 我可以通过 OAuth 1.0 身份验证成功使用 "update/status" 推特 api 发送 post。但是当我在查询字符串中写逗号时,api returns 401.
- https://api.twitter.com/1.1/statuses/update.json?status=test1 测试 2
- https://api.twitter.com/1.1/statuses/update.json?status=test1, test2
例如,第一个请求运行成功但第二个请求运行失败。唯一的区别是逗号。我正在使用 Uri.EscapeDataString()。但它不起作用。我错过了什么?请帮我。谢谢。
public class OAuth1Manager : IOAuth1Service
{
private OAuth1Request _request;
private List<string> _requestParameters;
private List<string> _signatureParameters;
public List<string> GetQueryStrings(string url)
{
var splitted = url.Split("?");
if (splitted.Length > 1)
{
return splitted[1].Split("&").ToList();
}
return new string[0].ToList();
}
public string GetSignedOAuthString(OAuth1Request request)
{
_request = request;
_requestParameters = new List<string>
{
$"oauth_consumer_key={_request.OAuth.ConsumerKey}",
$"oauth_signature_method=HMAC-SHA1",
$"oauth_timestamp={GetTimeStamp()}",
$"oauth_nonce={GetNonce()}",
$"oauth_token={request.OAuth.AccessToken}",
$"oauth_version=1.0",
};
_signatureParameters = new List<string>();
_signatureParameters.AddRange(_requestParameters);
_signatureParameters.AddRange(GetQueryStrings(_request.Url));
_requestParameters.Add($"oauth_signature={GetSignature()}");
for (int i = 0; i < _requestParameters.Count; i++)
{
var parameter = _requestParameters[i];
var splitted = parameter.Split("=");
_requestParameters[i] = $"{splitted[0]}=\"{splitted[1]}\"";
}
return $"OAuth {_requestParameters.JoinAsString(",")}";
}
private string GetNonce()
{
var rand = new Random();
var nonce = rand.Next(1000000000);
return nonce.ToString();
}
private string GetSignatureBaseString()
{
var sortedList = new List<string>(_signatureParameters);
sortedList.Sort();
var requestParametersSortedString = sortedList.JoinAsString("&");
var url = ConstructRequestUrl();
return _request.Method.GetEnumDescription().ToUpper() + "&" + Uri.EscapeDataString(url) + "&" +
Uri.EscapeDataString(requestParametersSortedString);
}
private string ConstructRequestUrl()
{
var uri = new Uri(_request.Url, UriKind.Absolute);
var normUrl = string.Format("{0}://{1}", uri.Scheme, uri.Host);
if (!(uri.Scheme == "http" && uri.Port == 80 ||
uri.Scheme == "https" && uri.Port == 443))
normUrl += ":" + uri.Port;
normUrl += uri.AbsolutePath;
return normUrl;
}
private string GetSignature()
{
var hmacsha1 = new HMACSHA1();
var key = Uri.EscapeDataString(_request.OAuth.ConsumerSecret) + "&" + (string.IsNullOrEmpty(_request.OAuth.TokenSecret)
? ""
: Uri.EscapeDataString(_request.OAuth.TokenSecret));
hmacsha1.Key = Encoding.ASCII.GetBytes(key);
var dataBuffer = Encoding.ASCII.GetBytes(GetSignatureBaseString());
var hashBytes = hmacsha1.ComputeHash(dataBuffer);
return Uri.EscapeDataString(Convert.ToBase64String(hashBytes));
}
private string GetTimeStamp()
{
var ts = DateTime.UtcNow - new DateTime(1970, 1, 1, 0, 0, 0, 0);
return Convert.ToInt64(ts.TotalSeconds).ToString();
}
}
我用 %2C 替换了所有逗号,例如 "test1%2Ctest2" 而不是 "test1,test2" 然后它起作用了。