【问题标题】:Unauthorized result and PostAsJsonAsync<T> causing javascript error Blazor Server未经授权的结果和 PostAsJsonAsync<T> 导致 javascript 错误 Blazor Server
【发布时间】:2020-09-01 00:43:35
【问题描述】:

我有一个场景,当登录失败时,Api 必须返回 UnAuthorized 结果。但是,来自 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
        }

【问题讨论】:

    标签: asp.net-core blazor dotnet-httpclient blazor-server-side asp.net-blazor


    【解决方案1】:

    第一个选项当然是更改您的 Action 方法并使用.Token.JwtToken == null 返回一个有效的 Dto 结果。然后您的 Blazor 代码可以保持原样。

    这将是我的首选方式,登录请求本身不是“未授权”,它只是被拒绝。这里的return Unauthorized(); 非常值得商榷。

    如果你仍然想在客户端处理它:你现在无法得到响应状态,因为你直接转换了表单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) { ... }
    
      }
    

    【讨论】:

    • 不是问题。在给定的场景中,如果身份管理器的结果不成功,则未经授权的结果将是操作
    • 结果的序列化是我猜的问题,因为预期的结果是一个 IdentityWithTokenDto,它强制端点返回一个我认为很奇怪的 IdentityWithTokenDto 实例。跨度>
    • 这将迫使我将方法更改为 GET 而不是 POST 方法?
    • 你的回答有点不对,但它帮助我弄清楚了。
    猜你喜欢
    • 2019-01-29
    • 2021-11-21
    • 2023-03-10
    • 2016-04-18
    • 2017-04-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多