.net core 3.0 Signalr - 05 使用jwt将用户跟signalr关联

Posted xiexingen

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了.net core 3.0 Signalr - 05 使用jwt将用户跟signalr关联相关的知识,希望对你有一定的参考价值。

Signalr是以Group、Connect为核心来进行推送,比如,给某个组、某个连接来推送,但实际场景中,核心应该是某个组、某个人;然而一个人可以对应多个连接(浏览器多个tab页);本节就来介绍下自行管理人、组、连接这些关系
由于signalr连接的时候不那么方便附带header和cookie(因为推送独立成一个子系统了),实际实现中采用以url query的形式附带上token,然后服务器端自定义解析token得到用户信息;

服务器端实现

  • ConfigureServices中添加服务相关方法,代码如下,完整代码

    public void ConfigureServices(IServiceCollection services)
    
        var appSection = Configuration.GetSection("App");
        services.Configure<AppSetting>(option => appSection.Bind(option));
        var appSetting = appSection.Get<AppSetting>();
    
        services.AddSingleton<SignalrRedisHelper>();
    
        // services.AddHostedService<ClearBackGroundService>();
    
        services.AddAuthentication(options =>
        
            options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            options.DefaultForbidScheme = JwtBearerDefaults.AuthenticationScheme;
        )
        .AddJwtBearer(option =>
        
            option.SecurityTokenValidators.Clear();
            option.SecurityTokenValidators.Add(new UserTokenValidation()); ;
    
            option.Events = new JwtBearerEvents()
            
                OnMessageReceived = context =>
                
                    var userId = context.Request.Query["userId"].FirstOrDefault();
                    if (!string.IsNullOrWhiteSpace(userId))
                    
                        context.Token = userId;
                    
                    return Task.CompletedTask;
                
            ;
        );
    
        services.AddCors(options => options.AddPolicy(corsPolicy, builder =>
        
            builder
                  .SetIsOriginAllowedToAllowWildcardSubdomains()
                  .WithOrigins(appSetting.CORS.Split(","))
                  .AllowAnyMethod()
                  .AllowCredentials()
                  .AllowAnyHeader()
                  .Build();
        ));
    
        services.AddControllers()
            .AddNewtonsoftJson(options => options.SerializerSettings.ContractResolver = new CamelCasePropertyNamesContractResolver())
            .ConfigureApiBehaviorOptions(options =>
            
                options.InvalidModelStateResponseFactory = context =>
                
                    var result = new BadRequestObjectResult(context.ModelState);
                    result.ContentTypes.Add(MediaTypeNames.Application.Json);
                    // result.ContentTypes.Add(MediaTypeNames.Application.Xml);
    
                    return result;
                ;
            )
            .SetCompatibilityVersion(CompatibilityVersion.Version_3_0);
    
        // 添加Signalr
        services.AddSignalR(config =>
        
            if (_webEnv.IsDevelopment())
            
                config.EnableDetailedErrors = true;
            
        )
        // 支持MessagePack
        .AddMessagePackProtocol()
        // 使用redis做底板 支持横向扩展 Scale-out
        .AddStackExchangeRedis(o =>
          
              o.ConnectionFactory = async writer =>
              
                  var config = new ConfigurationOptions
                  
                      AbortOnConnectFail = false,
                      // Password = "changeme",
                      ChannelPrefix = "__signalr_",
                  ;
                  //config.EndPoints.Add(IPAddress.Loopback, 0);
                  //config.SetDefaultPorts();
                  config.DefaultDatabase = appSetting.SignalrRedisCache.DatabaseId;
                  var connection = await ConnectionMultiplexer.ConnectAsync(appSetting.SignalrRedisCache.ConnectionString, writer);
                  connection.ConnectionFailed += (_, e) =>
                  
                      Console.WriteLine("Connection to Redis failed.");
                  ;
    
                  if (connection.IsConnected)
                  
                      Console.WriteLine("connected to Redis.");
                  
                  else
                  
                      Console.WriteLine("Did not connect to Redis");
                  
    
                  return connection;
              ;
          );
    

    其中,SignalrRedisHelper 为redis辅助方法,详情请参见
    UserTokenValidation 为自定义token解析方法,详情请参见,由于历史遗留问题,此处直接使用了userId,建议的做法是传递jwttoken,然后服务器端解析jwt token得到用户信息

Hub中跟用户关联

在Hub中通过Context.User.Identity.Name可以获取到解析的值,通过这种关系来跟用户关联上,当然,也可以自定义修改使用其他信息,比如Email或其他自定义的名称,具体请google

更多内容请通过快速导航查看下一篇

快速导航

标题 内容
索引 .net core 3.0 Signalr - 实现一个业务推送系统
上一篇 .net core 3.0 Signalr - 04 使用Redis做底板来支持横向扩展
下一篇 .net core 3.0 Signalr - 06 业务实现-业务分析
源码地址 源码
官方文档 官方文档

技术图片

以上是关于.net core 3.0 Signalr - 05 使用jwt将用户跟signalr关联的主要内容,如果未能解决你的问题,请参考以下文章

.net core 3.0 Signalr - 05 使用jwt将用户跟signalr关联

.net core 3.0 Signalr - 05 使用jwt将用户跟signalr关联

.net core 3.0 Signalr - 07 业务实现-服务端 自定义管理组用户连接

.net core 3.0 Signalr - 07 业务实现-服务端 自定义管理组用户连接

.net core 3.0 Signalr - 03 使用MessagePack压缩传输内容

.net core 3.0 Signalr - 03 使用MessagePack压缩传输内容