背景
我有一个具有 Twitter 应用程序设置的后端应用程序,我可以查询和提取用户推文/帖子数据。这很棒,但是,现在在前端我还没有完整的 Twitter 集成设置。我的意思是,在前端,用户可以输入任何 Twitter 用户名,并且我想确定输入的 Twitter 用户名实际上属于该用户。使用 Twitter 应用程序 key ,您可以提取任何 Twitter 帐户的公共(public) Twitter 数据,这非常适合大规模数据摄取,在我的情况下,可以进行概念验证工作。目前,我需要在后端强制执行这样的假设:为特定 Twitter 屏幕名称分析的数据也归我的 Web 应用程序上的帐户用户所有。
提议的 Twitter 解决方案
这是我一直在尝试遵循的一堆引用文档。
https://developer.twitter.com/en/docs/basics/authentication/guides/log-in-with-twitter https://developer.twitter.com/en/docs/basics/authentication/api-reference/request_token https://oauth.net/core/1.0/#anchor9 https://oauth.net/core/1.0/#auth_step1
我一直在尝试遵循这一点,并且对下面发布的代码进行了不同的排列(一种没有回调 URL 作为参数,一种带有等等),但在这一点上,并没有太大不同。我还没有取得任何成功,而且已经过去几天了,这让我很沮丧。
代码
这是我尝试遵循文档中上面提出的 OAuth 规范。请注意,这是 ASP.NET Core 2.2 + 代码。另外,这只是 Twitter OAuth 身份验证和授权指南中第 1 步的代码。
public async Task<string> GetUserOAuthRequestToken()
{
int timestamp = (Int32)(DateTime.UtcNow.Subtract(new DateTime(1970, 1, 1))).TotalSeconds;
string nonce = Convert.ToBase64String(Encoding.ASCII.GetBytes(timestamp.ToString()));
string consumerKey = twitterConfiguration.ConsumerKey;
string oAuthCallback = twitterConfiguration.OAuthCallback;
string requestString =
twitterConfiguration.EndpointUrl +
OAuthRequestTokenRoute;
string parameterString =
$"oauth_callback={WebUtility.UrlEncode(twitterConfiguration.OAuthCallback)}&" +
$"oauth_consumer_key={twitterConfiguration.ConsumerKey}&" +
$"oauth_nonce={nonce}&" +
$"oauth_signature_method=HMAC_SHA1&" +
$"oauth_timestamp={timestamp}" +
$"oauth_version=1.0";
string signatureBaseString =
"POST&" +
WebUtility.UrlEncode(requestString) +
"&" +
WebUtility.UrlEncode(parameterString);
string signingKey =
twitterConfiguration.ConsumerSecret +
"&" + twitterConfiguration.AccessTokenSecret;
byte[] signatureBaseStringBytes = Encoding.ASCII.GetBytes(signatureBaseString);
byte[] signingKeyBytes = Encoding.ASCII.GetBytes(signingKey);
HMACSHA1 hmacSha1 = new HMACSHA1(signingKeyBytes);
byte[] signature = hmacSha1.ComputeHash(signatureBaseStringBytes);
string authenticationHeaderValue =
$"oauth_nonce=\"{nonce}\", " +
$"oauth_callback=\"{WebUtility.UrlEncode(twitterConfiguration.OAuthCallback)}\", " +
$"oauth_signature_method=\"HMAC_SHA1\", " +
$"oauth_timestamp=\"{timestamp}\", " +
$"oauth_consumer_key=\"{twitterConfiguration.ConsumerKey}\", " +
$"oauth_signature=\"{Convert.ToBase64String(signature)}\", " +
$"oauth_version=\"1.0\"";
HttpRequestMessage request = new HttpRequestMessage();
request.Method = HttpMethod.Post;
request.RequestUri = new Uri(
baseUri: new Uri(twitterConfiguration.EndpointUrl),
relativeUri: OAuthRequestTokenRoute);
request.Content = new FormUrlEncodedContent(
new Dictionary<string, string>() {
{ "oauth_callback", twitterConfiguration.OAuthCallback }
});
request.Headers.Authorization = new AuthenticationHeaderValue("OAuth",
authenticationHeaderValue);
HttpResponseMessage httpResponseMessage = await httpClient.SendAsync(request);
if (httpResponseMessage.IsSuccessStatusCode)
{
return await httpResponseMessage.Content.ReadAsStringAsync();
}
else
{
return null;
}
}
注释 我也尝试从参数中删除回调 URL,但没有成功。我已经尝试了各种略有不同的排列(对我的签名进行urlencode,在查询字符串中添加回调URL,将其删除等),但此时我已经失去了我已经尝试过但没有尝试过的排列(编码,引号等) .).
忽略我尚未将响应序列化到模型中的事实,因为目标是首先达到成功状态代码!
我也有一个针对此方法的集成测试设置,并且我不断收到 400 Bad Request,没有附加信息(这是有道理的),但绝对对调试没有帮助。
[Fact]
public async Task TwitterHttpClientTests_GetOAuthRequestToken_GetsToken()
{
var result = await twitterHttpClient.GetUserOAuthRequestToken();
Assert.NotNull(result);
}
顺便说一句,我还有其他一些问题:
- 有没有一种方法可以验证用户的 Twitter 帐户而无需访问 通过 OAuth 流程?我问这个的原因是因为 事实证明,通过 OAuth 流程很困难
- 在后端执行 Twitter 登录工作流程的第一步并将响应返回到前端是否安全?响应 将携带敏感 token 和 token secret 。 (如果我回答 我本人会说你必须这样做,否则你 必须将应用程序 secret 硬编码到前端配置中 哪个更糟)。我问这个是因为这一直在我的意识中 自从我开始做这件事以来,我有点担心。
- 是否有适用于 C# ASP.NET Core 的 OAuth 帮助程序库可以让这一切变得更容易?
最佳答案
我通过编写单元测试并阅读 Creating A Signature 上的 Twitter 文档解决了这个问题。 。由于该示例提供了键和结果,因此可以验证您的代码是否正确。
既然你询问了图书馆 - 我写了 LINQ to Twitter希望能帮助像我这样的人完成这项艰巨的任务。
除了签名之外,当您的代码通过 OAuth 流程工作时,页面导航也可能具有挑战性。请查看 Obtaining user access tokens 上的 Twitter 文档为了更好地理解这一点。我还在 LINQ to Twitter Wiki Securing your Applications 上记录了这一点。 。以下是如何与 LINQ to Twitter 配合使用:
- 首先,我有一个带有
Begin
操作的OAuthController
,用于将用户重定向到以启动身份验证过程:
public async Task<ActionResult> Begin()
{
//var auth = new MvcSignInAuthorizer
var auth = new MvcAuthorizer
{
CredentialStore = new SessionStateCredentialStore(HttpContext.Session)
{
ConsumerKey = configuration["Twitter:ConsumerKey"],
ConsumerSecret = configuration["Twitter:ConsumerSecret"]
}
};
string twitterCallbackUrl = Request.GetDisplayUrl().Replace("Begin", "Complete");
return await auth.BeginAuthorizationAsync(new Uri(twitterCallbackUrl));
}
请注意,它使用 MvcSignInAuthorizer
,通过 CredentialStore
属性传入凭据。如果您使用自己的原始代码,则需要使用 Authorization
header 设置 HTTP 请求。
接下来,请注意我正在修改当前 URL,以便它将引用相同的 Controller ,但具有 Complete
端点。这是发送到 Twitter 授权的 oauth_callback
。
- 该流程会将用户重定向到 Twitter 网站,他们会授权您的应用,然后使用
oauth_callback
将用户重定向回您的网站。处理方法如下:
public async Task<ActionResult> Complete()
{
var auth = new MvcAuthorizer
{
CredentialStore = new SessionStateCredentialStore(HttpContext.Session)
};
await auth.CompleteAuthorizeAsync(new Uri(Request.GetDisplayUrl()));
// This is how you access credentials after authorization.
// The oauthToken and oauthTokenSecret do not expire.
// You can use the userID to associate the credentials with the user.
// You can save credentials any way you want - database,
// isolated storage, etc. - it's up to you.
// You can retrieve and load all 4 credentials on subsequent
// queries to avoid the need to re-authorize.
// When you've loaded all 4 credentials, LINQ to Twitter will let
// you make queries without re-authorizing.
//
//var credentials = auth.CredentialStore;
//string oauthToken = credentials.OAuthToken;
//string oauthTokenSecret = credentials.OAuthTokenSecret;
//string screenName = credentials.ScreenName;
//ulong userID = credentials.UserID;
//
return RedirectToAction("Index", "Home");
}
您再次可以看到我正在使用 MvcAuthorizer
并完成请求。完成请求后,您将能够提取 oauth_token
和 oauth_token_secret
,以及 screen_name
和 user_id
.您可以保存这些工件并在该用户的所有后续事件中重复使用它们,从而使他们的体验更好,因为他们不必在每次您需要发出请求时都登录。
关于您的验证问题,有一个 Verify Credentials端点。
LINQ to Twitter 有一个 ASP.NET Core Sample , API Samples 100% API 覆盖率,以及 Wiki 上的完整文档如果您想了解更多信息。
关于c# - ASP NET Core Twitter OAuth 请求 token 问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60688871/