在 ASP .NET Core 9 Razor Pages Web 应用程序中通过 Web API 进行身份验证(带有身份)

问题描述 投票:0回答:1

我有一个使用身份的 ASP .NET Core 9 Razor Pages Web 应用程序。我从模板创建了它,附加了我的自定义 DbContext 并搭建了一些身份页面(

Identity/Pages/Account/Login
就是其中之一)。登录表单是标准的 - 它包含一个
<form>
和多个
<input>
(通过
InputModel
连接到
asp-for
的字段)和一个
<button type="submit">

Login.cshtml.cs
文件中,我通过
SignInManager<MyUserType>
执行登录(我省略了所有检查以简化示例代码):

[BindProperty]
public InputModel Input { get; set; }

...

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
{
    returnUrl ??= Url.Content("~/");

    if (ModelState.IsValid)
    {
        var result = await _signInManager.PasswordSignInAsync(Input.UserName, Input.Password, Input.RememberMe);
        if (result.Succeeded)
        {
            return LocalRedirect(returnUrl);
        }
        else
        {
            ModelState.AddModelError(string.Empty, _localizer["LoginError"].Value);
            return Page();
        }
    }

    // If we got this far, something failed, redisplay form
    return Page();
}

现在我想添加 Web API 以便能够拥有其他消费者(iOS/Android 应用程序、PHP/Go 客户端等)。使用最少的 API 语法,我已经实现了

Login
(简化):

app.MapPost("/api/LoginUser", async (InputModel input, SignInManager<MyUserType> signInManager) =>
{
    var result = await signInManager.PasswordSignInAsync(input.UserName, input.Password, input.RememberMe);
    if (result.Succeeded)
    {
        return Results.Ok();
    }
    return Results.BadRequest($"SignInResult: {result}");
});

现在在发布登录表单时,我通过

HttpClient
执行 API 调用,如下所示:

public async Task<IActionResult> OnPostAsync(string returnUrl = null)
    {
        returnUrl ??= Url.Content("~/");
    
        if (ModelState.IsValid)
        {
            using (var client = new HttpClient())
            {
                 var response = await client.PostAsJsonAsync($"{Request.Scheme}://{Request.Host}{Request.PathBase}/api/LoginUser", Input);
                 switch (response.StatusCode)
                 {
                     case System.Net.HttpStatusCode.OK:
                         //why user is not authenticated here and I need to perform another sign in?
                         if (!User.Identity.IsAuthenticated)
                             await _signInManager.PasswordSignInAsync(Input.Username, Input.Password, Input.RememberMe);
                         return Redirect(returnUrl);
                         break;

                     case System.Net.HttpStatusCode.BadRequest:
                         var errorText = response.Content.ReadAsStringAsync().Result;
                         ModelState.AddModelError(string.Empty, errorText);
                         return Page();
                         break;
            }
        }
    
        // If we got this far, something failed, redisplay form
        return Page();
    }

这里的问题是,从 PageModel 的角度来看,用户仍未经过身份验证,我需要执行另一次登录。我觉得这是不正确的方式,但我不知道如何修复它。

那么如何通过 Web API 从 Razor 页面正确登录呢?附:我可以发布我的

Program.cs
,但我真的不知道是否需要它。

asp.net-core authentication asp.net-core-webapi asp.net-identity razor-pages
1个回答
0
投票

在 Razor 页面中,

User.Identity
是通过视图上下文分配的,视图上下文是在您最初访问页面时创建的。

我认为您正在尝试访问

User.Identity
对象,该对象 尚未更新,因为您没有刷新页面

由于您的 API 操作已返回成功,您可以假设用户已登录,因此只需执行重定向即可。

switch (response.StatusCode)
{
   case System.Net.HttpStatusCode.OK:
      return Redirect(returnUrl);
      break;
   ...
}
© www.soinside.com 2019 - 2024. All rights reserved.