Получение HTTP 400 при попытке использовать токен обновления для аутентификации APIC#

Место общения программистов C#
Ответить
Anonymous
 Получение HTTP 400 при попытке использовать токен обновления для аутентификации API

Сообщение Anonymous »

Проблема: механизм токена обновления не работает, когда срок действия токена истек. Обновить
токен запросить новый токен доступа и продолжить без перерыва < /p>
mobile < /strong> < /p>

Код: Выделить всё

    public App()
{
InitializeComponent();

MainPage = new AppShell();
}

protected override async void OnStart()
{
await GetValidAccessToken();
}

protected override async void OnResume()
{
await GetValidAccessToken();
}

public class TokenResponse
{
[JsonPropertyName("AccessToken")]
public string Token { get; set; }

[JsonPropertyName("RefreshToken")]
public string RefreshToken { get; set; }
}

private async Task GetValidAccessToken()
{
try
{
var accessToken = await SecureStorage.GetAsync("AuthToken");
var refreshToken = await SecureStorage.GetAsync("RefreshToken");
var email = await SecureStorage.GetAsync("UserEmail");

using (var httpClient = new HttpClient { BaseAddress = new Uri(AppSettings.UrlApi) })
{
httpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", accessToken);
var requestUri = "/api/v1/Users/all";
var response = await httpClient.GetAsync(requestUri);

if (response.StatusCode == HttpStatusCode.Unauthorized)
{
var refreshData = new MultipartFormDataContent();
refreshData.Add(new StringContent(refreshToken), "refreshToken");

response = await httpClient.PostAsync("/api/v1/UserAuth/RefreshToken", refreshData);

if (!response.IsSuccessStatusCode)
throw new Exception("Failed to refresh token.");

var rawContent = await response.Content.ReadAsStringAsync();
using (var stringReader = new StringReader(rawContent))
{
using (var jsonReader = new JsonTextReader(stringReader))
{
var tokenResponse = Newtonsoft.Json.JsonSerializer.Create().Deserialize(jsonReader);

if (tokenResponse == null)
throw new Exception("Failed to parse token response.");

await SecureStorage.SetAsync("AuthToken", "null");
await SecureStorage.SetAsync("RefreshToken", "null");

await SecureStorage.SetAsync("AuthToken", tokenResponse.Token);
await SecureStorage.SetAsync("RefreshToken", tokenResponse.RefreshToken);

var savedAuthToken = await SecureStorage.GetAsync("AuthToken");
var savedRefreshToken = await SecureStorage.GetAsync("RefreshToken");

await UpdateTokensInDatabase(email, tokenResponse.RefreshToken);

if (savedAuthToken != tokenResponse.Token || savedRefreshToken != tokenResponse.RefreshToken)
throw new Exception("Tokens not updated properly.");
}
}
}
else
throw new Exception($"Request failed with status code: {response.StatusCode}");
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}

private async Task  GetValidAccessTokenAsync()
{
var accessToken = await SecureStorage.GetAsync("AuthToken");
if (string.IsNullOrEmpty(accessToken) || IsTokenExpired(accessToken))
{
var refreshToken = await SecureStorage.GetAsync("RefreshToken");
if (!string.IsNullOrEmpty(refreshToken))
{
var newToken = await RefreshAccessTokenAsync(refreshToken);
if (!string.IsNullOrEmpty(newToken))
{
await SecureStorage.SetAsync("AuthToken", newToken);
return newToken;
}
}
return null;
}
return accessToken;
}

private bool IsTokenExpired(string token)
{
try
{
var handler = new System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler();
var jwt = handler.ReadJwtToken(token);
return jwt.ValidTo < DateTime.UtcNow.AddMinutes(1);
}
catch
{
return true;
}
}

private async Task RefreshAccessTokenAsync(string refreshToken)
{
using (var httpClient = new HttpClient { BaseAddress = new Uri(AppSettings.UrlApi) })
{
var content = new MultipartFormDataContent();
content.Add(new StringContent(refreshToken), "refreshToken");

var response = await httpClient.PostAsync("/api/v1/UserAuth/RefreshToken", content);
if (response.IsSuccessStatusCode)
{
var rawContent = await response.Content.ReadAsStringAsync();
var tokenResponse = Newtonsoft.Json.JsonConvert.DeserializeObject(rawContent);
if (tokenResponse != null && !string.IsNullOrEmpty(tokenResponse.Token))
{
if (!string.IsNullOrEmpty(tokenResponse.RefreshToken))
await SecureStorage.SetAsync("RefreshToken", tokenResponse.RefreshToken);
return tokenResponse.Token;
}
}
}
return null;
}

private async Task UpdateTokensInDatabase(string email, string refreshToken)
{
string accessToken = await GetValidAccessTokenAsync();

if (string.IsNullOrEmpty(accessToken))
{
await ShowAlertAsync("Session expired", "Please log in again.", "OK");
return;
}
using (var httpClient = new HttpClient { BaseAddress = new Uri(AppSettings.UrlApi) })
{
var tokenUpdateData = new MultipartFormDataContent();
tokenUpdateData.Add(new StringContent(email), "email");
tokenUpdateData.Add(new StringContent(refreshToken), "refreshToken");

var response = await httpClient.PostAsync("/api/v1/UserAuth/UpdateTokens", tokenUpdateData);

if (!response.IsSuccessStatusCode)
throw new Exception("Failed to update tokens in the database.");
}
api [/b]

Код: Выделить всё

[HttpPost("RegisterUser")]
public async Task  RegisterUser([FromForm] UserRegistrationRequest userRegistrationRequest)
{
try
{
UsersEntity user = await _usersRepository.FindByEmailAsync(userRegistrationRequest.Email);
if (user == null)
{
user = new UsersEntity
{
UserName = userRegistrationRequest.Name + "User",
Name = userRegistrationRequest.Name,
Email = userRegistrationRequest.Email,
Role = "User",
Groups = "[]",
Created_by = "System",
Created_date = DateTimeOffset.UtcNow.Date,
Images = null,
Number = userRegistrationRequest.Number,
ImagesId = userRegistrationRequest.Image_id,
DeviceToken = userRegistrationRequest.DeviceToken ?? null,
Point = 0,
Modified_by = userRegistrationRequest.Name,
IdentityId = Guid.NewGuid().ToString(),
};

var registerUser = await _signInManager.UserManager.CreateAsync(user);
if (!registerUser.Succeeded)
return BadRequest(registerUser.Errors);

var addPassword = await _signInManager.UserManager.AddPasswordAsync(user, userRegistrationRequest.Password);
if (addPassword.Succeeded == false) return BadRequest(addPassword.Errors);

return Ok("User registered successfully");
}

return Ok(user);
}
catch (Exception ex)
{
return BadRequest($"An error occurred: {ex.Message}");
}
}

[HttpPost("Login")]
public async Task Login([FromForm] string email, [FromForm] string password)
{
if (string.IsNullOrEmpty(email))
return BadRequest("Email cannot be empty.");

if (string.IsNullOrEmpty(password))
return BadRequest("Password cannot be empty.");

var user = await _usersRepository.FindByEmailAsync(email);

if (user == null) return NotFound("User Not Found or Password Invalid");

var signInResult = await _signInManager.CheckPasswordSignInAsync(user, password, false);
if (signInResult.Succeeded == false) return NotFound("User Not Found or Password Invalid");

var token = CreateToken(user);
var refreshToken = GenerateRefreshToken();
user.RefreshToken = refreshToken;
user.RefreshTokenExpiryTime = DateTime.UtcNow.AddDays(7);
await _usersRepository.UpdateAsync(user);

return Ok(new
{
Token = token,
RefreshToken = refreshToken
});
}

private string CreateToken(UsersEntity user)
{
var claims = new List
{
new(ClaimTypes.Name, user.UserName),
new(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString()),
};
var securityKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_config["Jwt:Key"]));
var credentials = new SigningCredentials(securityKey, SecurityAlgorithms.HmacSha256);

var Sectoken = new JwtSecurityToken(_config["Jwt:Issuer"],
_config["Jwt:Audience"],
claims,
expires: DateTime.Now.AddMinutes(120),
signingCredentials: credentials);

var token = new JwtSecurityTokenHandler().WriteToken(Sectoken);

return token;
}

private string GenerateRefreshToken()
{
var randomBytes = new byte[64];
using (var rng = RandomNumberGenerator.Create())
{
rng.GetBytes(randomBytes);
}
return Convert.ToBase64String(randomBytes);
}

[HttpPost("RefreshToken")]
public async Task  RefreshToken([FromForm] string refreshToken)
{
try
{
var user = await _usersRepository.FindByRefreshTokenAsync(refreshToken);

if (user == null || user.RefreshToken != refreshToken || user.RefreshTokenExpiryTime 

Подробнее здесь: [url]https://stackoverflow.com/questions/79756352/getting-http-400-when-attempting-to-use-refresh-token-for-api-authentication[/url]
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»