在刷新页面之前,Blazor Web Assembly (wasm) 不会使客户端 cookie 过期
Posted
技术标签:
【中文标题】在刷新页面之前,Blazor Web Assembly (wasm) 不会使客户端 cookie 过期【英文标题】:Blazor Web Assembly (wasm) won't expire client side cookie until page is refreshed 【发布时间】:2021-08-09 05:55:00 【问题描述】:我正在使用 Visual Studio 2019 中可用的最新 .NET 5 Blazor Web Assembly Core Hosted 模板。它已经支持开箱即用的身份验证。
问题是我可以像这样在 Startup.cs 中的 ConfigureServices(IServiceCollection services) 方法中使 .NET 托管(服务器)端的 Cookie 过期:
services.ConfigureApplicationCookie(options =>
options.AccessDeniedPath = "/Identity/Account/AccessDenied";
options.Cookie.Name = "MyCookie";
options.Cookie.HttpOnly = true;
options.ExpireTimeSpan = TimeSpan.FromMinutes(20);
options.LoginPath = "/Identity/Account/Login";
options.ReturnUrlParameter = CookieAuthenticationDefaults.ReturnUrlParameter;
options.SlidingExpiration = true;
);
但是,我的要求是,当会话在 20 分钟后到期时,应要求用户再次登录。我的问题是cookie仅在浏览器关闭或用户点击重新加载时才会过期。与此同时,我可以点击所有控制器,即使它们中有 [Authorize] 标签。理想的情况是当用户调用控制器然后它重定向到登录。
登录后会创建 Cookie。
当时间过去了,cookies 消失了,但用户仍然拥有所有权限。
【问题讨论】:
问题在于身份验证状态从未更新,因为 cookie 已过期,您的用户不再经过身份验证。该解决方案需要您的一些投资和知识。一般来说,您应该实现 Authentication State 提供程序,其中您应该有代码(循环)来检查 cookie 是否会在 20 分钟后过期,如果是,您可以警告您的用户这一事实,也许要求他注销再登录等。你这里可能还有代码来验证其他因素.... 在使用 IdentityServer 继续您的项目之前,请确保您已阅读 Microsoft 的这篇文章 (devblogs.microsoft.com/aspnet/…) 及其随附的 cmets。就我个人而言,我已经完成了 IdentityServer。 @enet 你有例子吗?我似乎在网上找不到任何东西。 不,抱歉,我不知道 Internet 上有任何代码示例这样做...但是,您应该首先检查 RevalidatingServerAuthenticationStateProvider 类及其派生类(注意:它是 Blazor 服务器,不是 WebAssembly,但它应该让您了解应该如何实现身份验证状态提供程序)。您需要覆盖某个可以访问您的 cookie 过期时间的方法,例如数据......并且您需要从该方法触发 MainLayout 组件可能订阅的事件以通知 cookie已经过期了,要去..etc 【参考方案1】:使用以下函数将 Utilities.js javascript 文件添加到客户端项目中的 wwwroot/js。
function initializeInactivityTimer(dotnetHelper)
var timer;
document.onmousemove = resetTimer;
document.onkeypress = resetTimer;
function resetTimer()
clearTimeout(timer);
timer = setTimeout(logout, 1200000);
function logout()
dotnetHelper.invokeMethodAsync("Logout");
确保将其添加到 wwwroot/index.html 的末尾
<script src="js/Utilities.js"></script>
在MainLayout.razor的Server项目中添加如下方法
[JSInvokable]
public async Task Logout()
var authState = await AuthenticationState;
if (authState.User.Identity.IsAuthenticated)
await SignOutManager.SetSignOutState();
NavigationManager.NavigateTo("authentication/logout");
确保将 MainLayout.razor 添加到顶部
@inject NavigationManager NavigationManager
@inject AuthenticationStateProvider AuthenticationStateProvider
@inject IJSRuntime js
@inject SignOutSessionStateManager SignOutManager
同时添加这个级联参数
[CascadingParameter]
public Task<AuthenticationState> AuthenticationState get; set;
仍然在 MainLayout.razor 上的 Task OnInitializedAsync() 上,像这样调用 javascript 函数:
await js.InvokeVoidAsync("initializeInactivityTimer", DotNetObjectReference.Create(this));
保留 StartUp.cs 上的所有修改。它们适用于用户重新加载或关闭浏览器时。如果没有鼠标移动或按键,这个js函数将注销用户。
参考
https://www.youtube.com/watch?v=cOV0uV_E6bU
https://github.com/gavilanch/BlazorMovies/tree/master/ASP.NET%20Core%205/Module%207%20-%20Security
【讨论】:
以上是关于在刷新页面之前,Blazor Web Assembly (wasm) 不会使客户端 cookie 过期的主要内容,如果未能解决你的问题,请参考以下文章