通过控制器登录的服务器端 Blazor

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

我有一个 blazor 应用程序,想为其创建一个登录过程。因此我知道我可以搭建并删除默认的 MVC 页面来实现这一目标。

另一方面,我曾经读到,通过使用登录过程的控制器也应该可以实现相同的目的:

我的控制器:

using BlazorTestAuthorisierung.Data;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Identity;
using Microsoft.AspNetCore.Mvc;

namespace BlazorTestAuthorisierung.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class LoginController : ControllerBase
    {

        private readonly SignInManager<Benutzer> _SignInManager;



        [HttpPost]
        public IActionResult Login([FromBody] Benutzer Benutzer)
        {
            var result = _SignInManager.PasswordSignInAsync(Benutzer.Email, Benutzer.EingegebenesPasswort, false, lockoutOnFailure: false).Result;


            if (result.Succeeded)
            {
                IActionResult response = Ok(new { result = "" });
                return response;
            }
            else
            {
                IActionResult response = Unauthorized(new { result=""});
                return response;
            }
        }
           

        public LoginController(SignInManager<Benutzer> signInManager)
        {
            _SignInManager = signInManager;
        }
       
    }
}

还有我的 blazor 登录信息

<EditForm Model=@LoginBenutzer OnValidSubmit="@OnLoginClick">
    <InputText @bind-Value="LoginBenutzer.Email" />
    <InputText @bind-Value="LoginBenutzer.EingegebenesPasswort" />
    <button type="submit">
        Anmelden
    </button>
</EditForm>

<AuthorizeView Roles=Administrator>
    <Authorized>
        Admin
    </Authorized>
</AuthorizeView>

@code{
    private Benutzer LoginBenutzer = new Benutzer() {
            Email = "",
            EingegebenesPasswort = ""
    };

    private async Task OnLoginClick()
    {

        var serialized = JsonConvert.SerializeObject(LoginBenutzer);
        var stringContent = new StringContent(serialized, Encoding.UTF8, "application/json");

        var result = await http.PostAsync($"{navigationManager.BaseUri}api/Login", stringContent).ConfigureAwait(false);
   
    }
    }

登录结果显示登录成功。然而,当我返回 Blazor 应用程序时,它仍然无法识别用户已登录,因为它始终显示“未登录”。

<AuthorizeView>

    <Authorized>
        Logged in
    </Authorized>
    <NotAuthorized>
        Not logged in
    </NotAuthorized>

</AuthorizeView>

我认为授权后控制器的状态不会回到blazor圈。

任何有关如何实现我的目标或根本不可能实现的目标的帮助,将不胜感激。

asp.net asp.net-mvc asp.net-identity blazor-server-side
1个回答
0
投票

我也尝试过,并遇到了与您相同的问题。然后我恍然大悟。当您使用 PostAsync 方法通过 WebClient 调用控制器时,它确实会在您的控制器中登录用户,但是该登录发生在与当前用户会话不同的会话中,因此您不会获取存储的会话的 cookie,因此就服务器而言,您的会话尚未登录。答案是使用您的表单来完成“action”标签的工作。所以你的控制器需要你已经建立的路由。您只需修改您的元素,如下所示

<EditForm Model=@LoginBenutzer action="api/Login" method="post">
    <InputText @bind-Value="LoginBenutzer.Email" name="username" />
    <InputText @bind-Value="LoginBenutzer.EingegebenesPasswort" name="password" />
    <input type="hidden" value="@("~/" + navManager.Uri.Replace(navManager.BaseUri, String.Empty)) name="returnUrl" />
    <button type="submit">
        Anmelden
    </button>
</EditForm>

因此,“action”标签告诉表单要发布到哪里,“method”标签告诉表单它是一个发布表单。您还会发现需要在输入中添加“名称”标签,当您编辑控制器方法时您会明白原因。我还添加了一个隐藏输入来保存返回 URL,因此登录时只会刷新您当时所在的任何页面。您必须修改控制器方法才能进行重定向,您将在下面看到这一点。因此,以这种方式修改控制器中的登录方法

[HttpPost]
public async Task<IActionResult> Login([FromForm] string name, [FromForm] 
       string password, [FromForm] string returnUrl)
{
    await _signInManager.PasswordSignInAsync(name, password, false, false);
    return Redirect(returnUrl ?? "/");
}

所以你看到你的方法参数是 [FromForm] 而不是 [FromBody]。您的参数名称需要与表单中的“名称”标签相对应。这是准系统,您实际上需要处理无效登录等等。但这是我能想到的最好的方法。

此外,您会发现这会导致页面刷新,因此如果您想在刷新过程中保留任何变量,请注入 ProtectedSessionStorage 并使用 SetAsync() 和 GetAsync() 来获取数据并将数据设置到会话数据存储中

© www.soinside.com 2019 - 2024. All rights reserved.