.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 业务实现-业务分析
源码地址
源码
官方文档
官方文档

二维码

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值