- Создал проект в Google Cloud Console.
- Включил Google Play Developer. API.
- На экране согласия OAuth был настроен тип внешнего приложения и добавлен https://www.googleapis.com/auth/androidpublisher в качестве области действия.
- Создал идентификатор клиента OAuth 2.0 с типом приложения Android и добавил имя пакета вместе с отпечатком SHA-1.
- Microsoft.Identity.Client
- System.Net.Http.Json
Ошибка запроса кода устройства:
{
" error": "invalid_client",
"error_description": "Неверный тип клиента".
>
Не удалось получить токен доступа.
Я реализовал поток OAuth для аутентификации кода устройства, как показано ниже:
Код: Выделить всё
public class GoogleAuthService
{
private static readonly HttpClient _httpClient = new HttpClient();
// Set your Client ID
private const string ClientId = "Your_Google_Client_ID";
// Set Google OAuth endpoints
private const string DeviceCodeEndpoint = "https://oauth2.googleapis.com/device/code";
private const string TokenEndpoint = "https://oauth2.googleapis.com/token";
// Scopes needed for the Google Play Developer API
private const string Scope = "https://www.googleapis.com/auth/androidpublisher";
public async Task GetAccessTokenAsync()
{
// Step 1: Request the device code
var deviceCodeResponse = await RequestDeviceCodeAsync();
if (deviceCodeResponse != null)
{
var deviceCode = deviceCodeResponse["device_code"].ToString();
var userCode = deviceCodeResponse["user_code"].ToString();
var verificationUrl = deviceCodeResponse["verification_url"].ToString();
var expiresIn = deviceCodeResponse["expires_in"].ToString();
var interval = int.Parse(deviceCodeResponse["interval"].ToString());
// Instruct the user to visit the URL and input the user code
Console.WriteLine($"Please visit {verificationUrl} and enter the code: {userCode}");
// Step 2: Poll for the token using the device code
return await PollForAccessTokenAsync(deviceCode, interval);
}
return null;
}
private async Task RequestDeviceCodeAsync()
{
var parameters = new FormUrlEncodedContent(new[]
{
new KeyValuePair("client_id", ClientId),
new KeyValuePair("scope", Scope)
});
var response = await _httpClient.PostAsync(DeviceCodeEndpoint, parameters);
var responseBody = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
return JObject.Parse(responseBody); // Return the device code response
}
Console.WriteLine($"Error requesting device code: {responseBody}");
return null;
}
private async Task PollForAccessTokenAsync(string deviceCode, int interval)
{
while (true)
{
await Task.Delay(interval * 1000); // Wait for the polling interval
var parameters = new FormUrlEncodedContent(new[]
{
new KeyValuePair("client_id", ClientId),
new KeyValuePair("device_code", deviceCode),
new KeyValuePair("grant_type", "urn:ietf:params:oauth:grant-type:device_code")
});
var response = await _httpClient.PostAsync(TokenEndpoint, parameters);
var responseBody = await response.Content.ReadAsStringAsync();
if (response.IsSuccessStatusCode)
{
var tokenResponse = JObject.Parse(responseBody);
var accessToken = tokenResponse["access_token"].ToString();
Console.WriteLine($"Access Token: {accessToken}");
return accessToken; // Return the access token
}
else if (response.StatusCode == System.Net.HttpStatusCode.BadRequest)
{
var error = JObject.Parse(responseBody)["error"].ToString();
if (error == "authorization_pending")
{
Console.WriteLine("Authorization pending, waiting...");
continue; // Keep polling
}
else
{
Console.WriteLine($"Error: {error}");
return null;
}
}
}
}
}
Код: Выделить всё
public async void LoginButtonClicked(Object sender, EventArgs e)
{
string accessToken = await _googleAuthService.GetAccessTokenAsync();
if (!string.IsNullOrEmpty(accessToken))
{
// Use the access token to make API calls to Google Play Developer API
Console.WriteLine($"Access Token: {accessToken}");
}
else
{
// Handle failure
Console.WriteLine("Failed to acquire access token.");
}
}
Код: Выделить всё
Подробнее здесь: https://stackoverflow.com/questions/790 ... ken-for-go