向 SignalR Core 请求添加 cookie

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

我正在使用 SignalR Core,由于架构原因,SignalR 服务器内容(集线器等)与我的主项目位于不同的域中。 客户有这个代码:

function connectToHub(url) {
    var connection = new signalR.HubConnectionBuilder()
           .withUrl(url, { headers: { "cookie": document.cookie } }).build();


    connection.on("NotificationUpdated", function (count) {
        console.log(count);
    });

    connection.start().then(function () {
        console.log('started');
    }).catch(function (err) {
        return console.error(err.toString());
    });

}

它可以正常连接到服务器,但我的中心中的 OnConnectedAsync 没有获取 cookie 或任何其他凭据(Context.User.Identity.Claims 为空)

这是 OnConnectedAsync 代码

        public async override Task OnConnectedAsync()
    {
        await Groups.AddToGroupAsync(Context.ConnectionId, ((ClaimsIdentity)Context.User.Identity)
               .Claims.FirstOrDefault(c => c.Type.Contains("email"))?.Value);
            await base.OnConnectedAsync();
    }

如果我将集线器放在与客户端相同的域中,它工作正常,但如果我将它放在不同的域中,客户端将停止附加cookie。

如何让客户端附加cookie?

(或者,如果有不同的方式将 connectionId 与用户声明映射,我也可以接受)

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

我在 Blazor Server(Cookie 身份验证)中遇到了与此问题类似的问题,经过大量搜索后,我找不到任何有用的内容。尽管如此,我还是设法以某种方式做到了,但我不确定这是否是最好的,甚至是一个好方法。

1- 在 razor 页面中注入 IHttpContextAccessor。

@inject IHttpContextAccessor HttpContextAccessor

2-从 IHttpContextAccessor 读取所有 cookie 并将它们添加到连接 cookie。

protected override async Task OnInitializedAsync()
{
    var uri = new UriBuilder(Navigation.Uri);

    hubConnection = new HubConnectionBuilder()
        .WithUrl(Navigation.ToAbsoluteUri("/chathub"), opti =>
        {
            if (HttpContextAccessor.HttpContext != null)
                foreach (var c in HttpContextAccessor.HttpContext.Request.Cookies)
                {
                    opti.Cookies.Add(new Cookie(c.Key, c.Value)
                    {
                            Domain = uri.Host, // Set the domain of the cookie
                            Path = uri.Path // Set the path of the cookie
                    });
                }
        })
        .Build();

    hubConnection.On<string, string>("ReceiveMessage", (user, message) =>
    {
        var encodedMsg = $"{user}: {message}";
        messages.Add(encodedMsg);
        InvokeAsync(StateHasChanged);
    });

    await hubConnection.StartAsync();
}

3- 现在您可以使用 AuthorizeAttribute 装饰您的中心。

[Authorize]
public class ChatHub : Hub
{
    public override Task OnConnectedAsync()
    {
        return base.OnConnectedAsync();
    }

    public async Task SendMessage(string user, string message)
    {
        await Clients.All.SendAsync("ReceiveMessage", user, message);
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.