我正在使用SignalR Core,由于架构原因,SignalR服务器的东西(Hubs等)与我的主要项目处于不同的领域。客户端有如下代码:
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)。声明为空)
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();
}
如果我把hub放在与客户端相同的域中,它工作正常,但如果我把它放在不同的域中,客户端停止附加cookie。
如何让客户端附加cookie ?
(或者,如果有不同的方法映射connectionId与用户声明,我也会很好)
我在Blazor服务器(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);
}
}