我有一个场景,当登录失败时,Api必须返回一个未经授权的结果。然而,序列化从 await HttpClient.PostJsonAsync(url, credentials)。 导致一个来自控制台的javascript错误,使登录页面无法如期运行.这里是我的位。
API代码。
[HttpPost("LoginV2")]
[SwaggerOperation(Tags = new[] { "Auth" })]
[ProducesResponseType(StatusCodes.Status200OK)]
[ProducesResponseType(StatusCodes.Status401Unauthorized)]
public async Task<IActionResult> LoginV2([FromBody] LoginDto login)
{
var result = await _signInManager.PasswordSignInAsync(login.Email, login.Password, false, false);
if (result.Succeeded)
{
var appUser = _userManager.Users.SingleOrDefault(r => r.UserName == login.Email);
var token = new TokenDto()
{
JwtToken = GenerateJwtToken(appUser),
RefreshToken = GenerateRefreshToken()
};
var appUserAuth = new IdentityWithTokenDto()
{
////......Omitted
};
return Ok(appUserAuth);
}
return Unauthorized();
}
Blazor代码
async Task SubmitCredentials()
{
var result = await Client.PostJsonAsync<IdentityWithTokenDto>(url, credentials);
loginFailure = string.IsNullOrEmpty(result.Token.JwtToken);
if (!loginFailure)
{
await tokenAuthenticationStateProvider.SetTokenAsync(result.Token.JwtToken, DateTime.Now.AddDays(1));
Navigation.NavigateTo("/",true);
}
}
我不知道如何处理未经授权的结果,因为httpclient会处理它,而blazor的javascript会向控制台抛出一个错误,使登录表单停止工作。
更新。下面的答案为我指出了解决方法,即不使用...。PostAsJsonAsync<> 并手动转换结果。
下面是更新后的代码。
var response = await Client.PostAsJsonAsync(url, credentials);
if (response.IsSuccessStatusCode)
{
var data = await response.Content.ReadAsAsync<IdentityWithTokenDto>();
await tokenAuthenticationStateProvider.SetTokenAsync(data.Token.JwtToken, DateTime.Now.AddDays(1));
Navigation.NavigateTo("/", true);
}
else
{
//Update the UI
}
第一个选择当然是改变你的Action方法,并返回一个有效的Dto结果。.Token.JwtToken == null
. 那么你的Blazor代码可以保持原样。
这是我喜欢的方式,Login req本身不是 "未授权",只是被拒绝了。在 return Unauthorized();
这里是非常值得商榷的。
如果你还想在客户端上处理:你现在无法获得响应状态,因为你直接转换了form Json。你就得把它拆开。
//var result = await Client.PostJsonAsync<IdentityWithTokenDto>(url, credentials);
var response = await Client.PostAsync(url, credentials);
if (response.IsSuccessStatusCode)
{
string json = await response.Content.ReadAsStringAsync();
// decode Json with System.Text.Json
}
else
{
// handle errors / unauth
if (response.StatusCode == HttpStatusCode.Unauthorized) { ... }
}