在Blazor中,要求身份验证对于所有浏览器选项卡是一个常见的问题。为了解决这个问题,我们可以使用SignalR来跟踪用户的登陆状态,然后通过在客户端使用JavaScript来确保所有打开的浏览器选项卡都处于同一身份验证状态。
下面是一个实现此解决方案的示例代码:
@inject IJSRuntime JSRuntime;
@code {
protected override async Task OnAfterRenderAsync(bool firstRender)
{
if (firstRender)
{
await JSRuntime.InvokeVoidAsync("registerBlazorAuthentication");
}
}
}
window.registerBlazorAuthentication = function () {
const connection = new signalR.HubConnectionBuilder()
.withUrl("/authhub")
.build();
connection.start()
.then(() => connection.invoke("AddToGroup", "authenticated"))
.catch(err => console.error(err.toString()));
connection.on("Unauthorized", function () {
document.location.reload(true);
});
connection.on("Refresh", function () {
document.location.reload(true);
});
}
public class AuthHub : Hub
{
private readonly IUserService _userService;
public AuthHub(IUserService userService)
{
_userService = userService;
}
public async Task AddToGroup(string groupName)
{
var userId = Context.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
if (!string.IsNullOrEmpty(userId))
{
await _userService.SetOnlineStatusAsync(Guid.Parse(userId), true);
await Groups.AddToGroupAsync(Context.ConnectionId, groupName);
}
}
public async Task RemoveFromGroup(string groupName)
{
var userId = Context.User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
if (!string.IsNullOrEmpty(userId))
{
await _userService.SetOnlineStatusAsync(Guid.Parse(userId), false);
await Groups.RemoveFromGroupAsync(Context.ConnectionId, groupName);
}
}
public override async Task OnDisconnectedAsync(Exception exception)
{
await RemoveFromGroup("authenticated");
await base.OnDisconnectedAsync(exception);
}
}
services.AddSignalR();
此解决