如何在服务器端 Blazor 中通过 HttpContext 注销
How to sign out over HttpContext in server-side Blazor
我在 Blazor 服务器端视图中访问 HttpContext
以手动注销。我将这一行添加到 Startup.cs
: services.AddHttpContextAccessor();
并使用 @inject IHttpContextAccessor HttpContextAccessor
将其注入到视图中。
我有一个尝试执行此代码的注销按钮:
await HttpContextAccessor.HttpContext.SignOutAsync("Cookies");
但我收到以下错误消息:
System.InvalidOperationException: 'Headers are read-only, response has already started.'
我怎样才能避免这个错误?
不要使用 IHttpContextAccessor
。
我猜你正在使用 ASP.NET Core Blazor 身份验证和授权 新系统。如果没有,那么现在就开始吧。生命太短暂,不能浪费在其他事情上。这是迄今为止为 Blazor 的身份验证和授权创建的最好的产品,它基于 Identity UI(当然,这不是 Blazor)。此外,还有一些组件可以控制应用程序中的身份验证和授权流程,例如在布局中显示 "Log in" 按钮和 "Log out" 按钮,根据身份验证状态交替更改等
请转到此页面并开始学习这个优秀的系统,然后来这里解决您遇到的具体问题:
https://docs.microsoft.com/en-us/aspnet/core/security/blazor/?view=aspnetcore-3.0&tabs=visual-studio
希望这对您有所帮助...
这也让我感到困惑,但您需要在 Razor 页面(而不是 Blazor 组件)上使用注销功能。创建一个注销页面并将您的注销代码放在 OnGetAsync()
方法中。
您的注销按钮可以link到注销页面。
如果您在通过模板创建项目时搭建了 Identity 并覆盖了旧的“LogOut.cshtml”,则“注销”按钮不会注销。假设您使用了默认的 IdentityUser 模型。我 运行 进入这个问题,如果其他人也遇到这个问题,我只想添加这个。我将 Blazor Server 与 .Net 5.0.3 的模板一起使用。您也可以删除后面的 Logout.cshtml.cs。
替换此 \Areas\Identity\Pages\Account\LogOut.cshtml
@page
@model LogoutModel
@{
ViewData["Title"] = "Log out";
}
<header>
<h1>@ViewData["Title"]</h1>
@{
if (User.Identity.IsAuthenticated)
{
<form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/", new { area = "" })" method="post">
<button type="submit" class="nav-link btn btn-link text-dark">Click here to Logout</button>
</form>
}
else
{
<p>You have successfully logged out of the application.</p>
}
}
</header>
替换为
@page
@using Microsoft.AspNetCore.Identity
@attribute [IgnoreAntiforgeryToken]
@inject SignInManager<IdentityUser> SignInManager
@functions {
public async Task<IActionResult> OnPost()
{
if (SignInManager.IsSignedIn(User))
{
await SignInManager.SignOutAsync();
}
return Redirect("~/");
}
}
我在 Blazor 服务器端视图中访问 HttpContext
以手动注销。我将这一行添加到 Startup.cs
: services.AddHttpContextAccessor();
并使用 @inject IHttpContextAccessor HttpContextAccessor
将其注入到视图中。
我有一个尝试执行此代码的注销按钮:
await HttpContextAccessor.HttpContext.SignOutAsync("Cookies");
但我收到以下错误消息:
System.InvalidOperationException: 'Headers are read-only, response has already started.'
我怎样才能避免这个错误?
不要使用 IHttpContextAccessor
。
我猜你正在使用 ASP.NET Core Blazor 身份验证和授权 新系统。如果没有,那么现在就开始吧。生命太短暂,不能浪费在其他事情上。这是迄今为止为 Blazor 的身份验证和授权创建的最好的产品,它基于 Identity UI(当然,这不是 Blazor)。此外,还有一些组件可以控制应用程序中的身份验证和授权流程,例如在布局中显示 "Log in" 按钮和 "Log out" 按钮,根据身份验证状态交替更改等
请转到此页面并开始学习这个优秀的系统,然后来这里解决您遇到的具体问题: https://docs.microsoft.com/en-us/aspnet/core/security/blazor/?view=aspnetcore-3.0&tabs=visual-studio
希望这对您有所帮助...
这也让我感到困惑,但您需要在 Razor 页面(而不是 Blazor 组件)上使用注销功能。创建一个注销页面并将您的注销代码放在 OnGetAsync()
方法中。
您的注销按钮可以link到注销页面。
如果您在通过模板创建项目时搭建了 Identity 并覆盖了旧的“LogOut.cshtml”,则“注销”按钮不会注销。假设您使用了默认的 IdentityUser 模型。我 运行 进入这个问题,如果其他人也遇到这个问题,我只想添加这个。我将 Blazor Server 与 .Net 5.0.3 的模板一起使用。您也可以删除后面的 Logout.cshtml.cs。
替换此 \Areas\Identity\Pages\Account\LogOut.cshtml
@page
@model LogoutModel
@{
ViewData["Title"] = "Log out";
}
<header>
<h1>@ViewData["Title"]</h1>
@{
if (User.Identity.IsAuthenticated)
{
<form class="form-inline" asp-area="Identity" asp-page="/Account/Logout" asp-route-returnUrl="@Url.Page("/", new { area = "" })" method="post">
<button type="submit" class="nav-link btn btn-link text-dark">Click here to Logout</button>
</form>
}
else
{
<p>You have successfully logged out of the application.</p>
}
}
</header>
替换为
@page
@using Microsoft.AspNetCore.Identity
@attribute [IgnoreAntiforgeryToken]
@inject SignInManager<IdentityUser> SignInManager
@functions {
public async Task<IActionResult> OnPost()
{
if (SignInManager.IsSignedIn(User))
{
await SignInManager.SignOutAsync();
}
return Redirect("~/");
}
}