SignalR - 将未经认证的用户映射到自定义ID
问题描述:
我想问一个简单的问题,它似乎是我找不到答案的。这里的JIST,我想用比其他Context.ConnectionId的唯一值,用于识别用户SignalR - 将未经认证的用户映射到自定义ID
所以,在我的HUB类我有这样的方法来生成一个唯一的GUID,当我开始连接调用此方法通过我的javascript
// My hub class
//...
public void GenerateGuid()
{
var guid = Guid.NewGuid().ToString();
Clients.Caller.myGuid(guid);
}
。
// My javascript
$.connection.hub.start().done(function(){
$.connection.chatHub.server.generateGuid();
});
$.connection.chatHub.client.myGuid = function (guid){
if (docCookies.getItem("guid") === null){
docCookies.setItem("guid", guid);
}
}
我还设置了IUserIdProvider(在这些文档https://www.asp.net/signalr/overview/guide-to-the-api/mapping-users-to-connections#IUserIdProvider建议使用比IPrincipal.Identity.Name以外的东西(因为我的不对用户进行认证这无论如何都不会工作)的定制实施者)
我认为这需要一点点修改,因为我不能确定如何在一个GUID没有定义
public class MyUserIdProvider : IUserIdProvider
{
public string GetUserId(IRequest request)
{
try
{
if (request.Cookies["guid"] != null)
{
return request.Cookies["guid"].Value;
}
}
catch (KeyNotFoundException kex)
{
// what to return here?
return Guid.NewGuid().ToString();
}
// what to return here?
return "";
}
}
的情况下返回。 (这是建立在我的Startup.cs所以不用担心要么)
GlobalHost.DependencyResolver.Register(typeof(IUserIdProvider),() => new MyUserIdProvider());
所以,有了这一切,我想有两个问题
- 我是不是设置了我
MyUserIdProvider
类以正确的方式吗? - 当我想要在我的Hub类中访问用户的ID时,我该如何访问它?我不认为我可以在调用像这样使用
Context.ConnectionId
了:return Groups.Add(Context.ConnectionId, [room]);
答
IUserIdProvider.GetUserId
在已建立的连接被调用,GenerateGuid
被调用之前。因此,cookies
在该阶段没有用处。你有自己的存储基础request
设置,例如:
public class MyUserIdProvider : IUserIdProvider
{
private static IDictionary<string, Guid> _tokens;
static MyUserIdProvider()
{
_tokens = new ConcurrentDictionary<string, Guid>();
}
private static string Key(IRequest request)
{
var key = request.QueryString["connectionToken"];
return key;
}
public static string UserId(IRequest request)
{
return _tokens[Key(request)].ToString();
}
public string GetUserId(IRequest request)
{
var key = Key(request);
_tokens[key] = Guid.NewGuid();
return _tokens[key].ToString();
}
}
随着数据的存储,您可以在枢纽方法从request
检索您的用户名:
public void GenerateGuid()
{
var guid = MyUserIdProvider.UserId(Context.Request);
Clients.Caller.myGuid(guid);
}