注销后中止连接 (SignalR)

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

注销后如何中止连接 (SignalR)?如何更改 SignOutAsync 方法以中止连接?

    [Route("api/[controller]")]
    [ApiController]
    public class AuthController : ControllerBase
    {
    
        [HttpPost("SignIn")]
        [AllowAnonymous]
        public async Task<IActionResult> SignInAsync([FromBody] User user)
        {
            if (user == null)
            {
                return BadRequest();
            }
    
            // User verification by user.Email and user.Password ... 
    
            if (verification == true)
            {
                var claims = new List<Claim> { new Claim(type: ClaimTypes.NameIdentifier, value: user.Email) };
                var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme));
    
                await HttpContext.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
    
                return Ok();
            }
    
            return Unauthorized();
        }
    
        [HttpDelete("SignOut")]
        [Authorize]
        public async Task SignOutAsync(IHubContext<Hubs.TestHub> hubContext)
        {
            if (hubContext != null)
            {
                var nameIdentifier = User?.FindFirst(ClaimTypes.NameIdentifier)?.Value;
                if (!string.IsNullOrWhiteSpace(nameIdentifier))
                {
                    await hubContext.Clients.User(nameIdentifier).SendAsync("TestHubNotify", $"Sign Out: {nameIdentifier}!");

                    // ???
                    // How do I Abort connections for user (ClaimTypes.NameIdentifier)?
                    // ???
                }
            }
    
            await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
        }
    }

SignInAsync方法验证用户数据(电子邮件和密码)。如果检查成功,用户会收到 cookie。

SignOutAsync 方法向所有用户连接发送消息。接下来,需要以某种方式中止所有用户连接。但如何做到这一点呢?然后cookies被删除。

asp.net-core asp.net-core-signalr
1个回答
0
投票

GlobalHost
包含在
ASP.NET SignalR
中,但在
ASP.NET Core
中已被移除,因此服务器无法直接调用该方法来中断连接。我们需要调用客户端自定义的
ForceDisconnect
方法并使用connection.stop();中断连接。

AuthController.cs

[Route("api/[controller]")]
[ApiController]
public class AuthController : ControllerBase
{
    private readonly IHubContext<TestHub> _hubContext;
    private readonly IConnectionManager _connectionManager;

    public AuthController(IHubContext<TestHub> hubContext, IConnectionManager connectionManager)
    {
        _hubContext = hubContext;
        _connectionManager = connectionManager;
    }

    [HttpDelete("SignOut")]
    [Authorize]
    public async Task<IActionResult> SignOutAsync()
    {
        // get userid
        var userId = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
        if (string.IsNullOrEmpty(userId))
        {
            return BadRequest("User identifier is missing.");
        }

        // get user connections by userid
        var connections = _connectionManager.GetConnections(userId);
        foreach (var connectionId in connections)
        {
            // call frontend method
            await _hubContext.Clients.Client(connectionId).SendAsync("ForceDisconnect");
        }

        await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme);
        return Ok();
    }
}

前端

connection.on("ForceDisconnect", function () {
    console.log("connection abort");
    connection.stop();
});

欲了解更多详情,您可以在这里查看我的源代码

我需要说明的是,这个方法是非常安全的。无论什么场景,如果单个客户端通过浏览器中的脚本执行代码,最多只会中断该客户端的连接,不会影响其他客户端。

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