Фон
У меня есть внутреннее приложение с настройкой приложения Twitter, и я могу запрашивать и извлекать пользовательские твиты / данные. Это здорово, однако, сейчас у меня нет полной настройки интеграции с Twitter. Под этим я подразумеваю, что на внешнем интерфейсе пользователь может ввести любое имя пользователя Twitter, и я хочу точно знать, что введенное имя пользователя Twitter действительно принадлежит пользователю. С помощью ключа приложения Twitter вы можете получить публичные c данные Twitter для любой учетной записи Twitter, которая хорошо подходит для загрузки больших объемов данных и, в моем случае, является доказательством концептуальной работы. На данный момент мне нужно, чтобы на бэк-энде было реализовано предположение, что данные, анализируемые для определенного псевдонима в Twitter, также принадлежат пользователю учетной записи в моем веб-приложении.
предлагаемое решение для 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-адреса обратного вызова в качестве параметров, один с et c.) но на данный момент не сильно отличается. У меня не было никакого успеха, и это было больше чем пару дней, что убивает меня.
Код
Это моя попытка следовать спецификации OAuth, предложенной выше в документации. Обратите внимание, что это ASP. NET Core 2.2 + code. Кроме того, это код только шага 1 в руководстве Twitter для аутентификации и авторизации OAuth.
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-адрес обратного вызова из параметров и это не сработало. Я перепробовал все виды немного разных перестановок (urlencoded моя подпись, добавил URL обратного вызова в строку запроса, удалил ее и т. Д. c), но в этот момент я потерял отслеживание того, которое я пробовал и не сделал (кодировки , цитаты и т. д. c.).
Не обращайте внимания на тот факт, что я еще не сериализовал ответ в модель, поскольку цель состоит в том, чтобы сначала ввести код состояния успеха!
У меня есть Настройка интеграционного теста также для этого метода, и я продолжаю получать 400 Bad Request без дополнительной информации (что имеет смысл), но абсолютно не помогает с отладкой.
[Fact]
public async Task TwitterHttpClientTests_GetOAuthRequestToken_GetsToken()
{
var result = await twitterHttpClient.GetUserOAuthRequestToken();
Assert.NotNull(result);
}
Кроме того, у меня были некоторые другие вопросы а также:
- Есть ли способ проверить учетную запись пользователя в Твиттере, не проходя через поток OAuth? Причина, по которой я спрашиваю об этом, заключается в том, что прохождение потока OAuth оказывается трудным
- Безопасно ли выполнять первый шаг рабочего процесса входа в Twitter на серверной части и возвращать ответ клиентской части? Ответ будет содержать чувствительный токен и секрет токена. (Если бы я сам ответил на этот вопрос, я бы сказал, что вы должны сделать это таким образом, в противном случае вам придется жестко кодировать секреты приложения в конфигурации внешнего интерфейса, что хуже). Я спрашиваю об этом, потому что это было в моем сознании, так как я начал это, и я немного волнуюсь.
- Есть ли вспомогательная библиотека OAuth для C# ASP. NET Ядро, которое может сделать это проще?