gpt4 book ai didi

c# - Blazor 服务器端应用程序的登录无法正常工作

转载 作者:行者123 更新时间:2023-12-02 14:52:14 25 4
gpt4 key购买 nike

我正在为 Asp.net core 3.0 Blazor 服务器端应用程序构建示例登录 Razor 组件。每当代码到达 SignInAsyc 方法时,它就会看起来挂起或锁定,因为代码停止进一步执行。我还尝试使用 PasswordSignInAsync 方法来切换逻辑,这给了我完全相同的结果。所有代码都将在该方法之前执行,但在执行该语句时卡住。我在这里缺少什么?

Razor 组件页面:

<div class="text-center">
<Login FieldsetAttr="fieldsetAttr" UsernameAttr="usernameAttr" PasswordAttr="passwordInput"
ButtonAttr="buttonAttr" ButtonText="Sign In" InvalidAttr="invalidAttr" />

</div>

@code {
Dictionary<string, object> fieldsetAttr =
new Dictionary<string, object>()
{
{"class", "form-group" }
};

Dictionary<string, object> usernameAttr =
new Dictionary<string, object>()
{
{"class", "form-control" },
{"type", "text" },
{"placeholder", "Enter your user name here." }
};

Dictionary<string, object> passwordInput =
new Dictionary<string, object>()
{
{"class", "form-control" },
{"type", "password" }
};

Dictionary<string, object> buttonAttr =
new Dictionary<string, object>()
{
{"type", "button" }
};

Dictionary<string, object> invalidAttr =
new Dictionary<string, object>()
{
{"class", "" },
{"style", "color: red;" }
};

Dictionary<string, object> validAttr =
new Dictionary<string, object>()
{
{"class", "" },
{"style", "color: green;" }
};

}

Razor 组件:

@inject SignInManager<IdentityUser> signInManager
@inject UserManager<IdentityUser> userManager

<div @attributes="FormParentAttr">
<form @attributes="LoginFormAttr">
<fieldset @attributes="FieldsetAttr">
<legend>Login</legend>
<label for="usernameId">Username</label><br />
<input @attributes="UsernameAttr" id="usernameId" @bind="UserName" /><br />
<label for="upasswordId">Password</label><br />
<input @attributes="PasswordAttr" id="passwordId" @bind="Password" /><br />
<button @attributes="ButtonAttr" @onclick="@(async e => await LoginUser())">@ButtonText</button>
@if (errorMessage != null && errorMessage.Length > 0)
{
<div @attributes="InvalidAttr">
@errorMessage
</div>
}
else if(successMessage != null && successMessage.Length > 0)
{
<div @attributes="ValidAttr">
@successMessage
</div>
}
</fieldset>
</form>
</div>

@code {

string successMessage = "";

private async Task LoginUser()
{
if(!String.IsNullOrEmpty(UserName))
{
var user = await userManager.FindByNameAsync(UserName);
var loginResult =
await signInManager.CheckPasswordSignInAsync(user, Password, false);



if(loginResult.Succeeded)
{
await signInManager.SignInAsync(user, true);
successMessage = $"{UserName}, signed in.";
errorMessage = "";
}
else
{
successMessage = "";
errorMessage = "Username or password is incorrect.";
}
}
else
{
successMessage = "";
errorMessage = "Provide a username.";
}
}

[Parameter]
public Dictionary<string, object> FormParentAttr { get; set; }

[Parameter]
public Dictionary<string, object> LoginFormAttr { get; set; }

[Parameter]
public Dictionary<string, object> FieldsetAttr { get; set; }

[Parameter]
public Dictionary<string, object> UsernameAttr { get; set; }

[Parameter]
public Dictionary<string, object> PasswordAttr { get; set; }

[Parameter]
public Dictionary<string,object> ButtonAttr { get; set; }

[Parameter]
public Dictionary<string, object> InvalidAttr { get; set; }

private string UserName { get; set; }
private string Password { get; set; }

[Parameter]
public string ButtonText { get; set; }

[Parameter]
public Dictionary<string, object> ValidAttr { get;set; }

public string errorMessage { get; set; }

}

最佳答案

基本上,发生这种情况是因为 SigninManger::SignInAsync() 实际上会尝试通过 HTTP发送 cookie 以指示该用户已已经登录。但是此时处理 Blazor 服务器端时,根本没有可用的 HTTP 响应,只有 WebSocket 连接(信号R)。

如何修复

简而言之,Signin 就是保存用户凭据/cookies/...,以便 WebApp 知道客户端是谁。由于您使用的是 Blazor 服务器端,因此您的客户端将通过 WebSocket 连接与服务器进行通信。无需通过 HTTP 发送 cookie。因为你的WebApp已经知道当前用户是谁。

要解决此问题,请首先注册 IHostEnvironmentAuthenticationStateProvider 服务:

services.AddScoped<AuthenticationStateProvider, RevalidatingIdentityAuthenticationStateProvider<IdentityUser>>();
services.AddScoped<IHostEnvironmentAuthenticationStateProvider>(sp => {
// this is safe because
// the `RevalidatingIdentityAuthenticationStateProvider` extends the `ServerAuthenticationStateProvider`
var provider = (ServerAuthenticationStateProvider) sp.GetRequiredService<AuthenticationStateProvider>();
return provider;
});

然后创建一个主体并替换旧的主体。

@inject AuthenticationStateProvider AuthenticationStateProvider@inject IHostEnvironmentAuthenticationStateProvider HostAuthentication...var user = await userManager.FindByNameAsync(UserName);var valid= await signInManager.UserManager.CheckPasswordAsync(user, Password);if (valid){    var principal = await signInManager.CreateUserPrincipalAsync(user);    var identity = new ClaimsIdentity(        principal.Claims,        Microsoft.AspNetCore.Authentication.Cookies.CookieAuthenticationDefaults.AuthenticationScheme    );    principal = new System.Security.Claims.ClaimsPrincipal(identity);    signInManager.Context.User = principal;    HostAuthentication.SetAuthenticationState(Task.FromResult(new AuthenticationState(principal)));    // now the authState is updated    var authState = await AuthenticationStateProvider.GetAuthenticationStateAsync();    successMessage = $"{UserName}, signed in.";    errorMessage = "";}else{    successMessage = "";    errorMessage = "Username or password is incorrect.";}

演示

enter image description here

并检查authState:

enter image description here

关于c# - Blazor 服务器端应用程序的登录无法正常工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58387683/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com