如何使用 JWT Token 管理用户身份?

Posted

技术标签:

【中文标题】如何使用 JWT Token 管理用户身份?【英文标题】:How can I Use JWT Token to Manage User Identity? 【发布时间】:2020-10-28 09:09:09 【问题描述】:

我有一个使用 JWT 身份验证并在登录时发出令牌的 API 项目。

我正在使用 ASP.NET 核心 MVC 项目作为客户端

在客户端应用程序中成功登录后,将返回一个 JWT 令牌, 现在我有了 JWT 令牌,

如何在我的客户端应用程序中访问 User.Identity?

我需要做什么才能在整个应用程序中获取和使用用户身份?

如何在客户端应用程序中管理授权?

API 项目

  // configure strongly typed settings objects
            var appSettingsSection = Configuration.GetSection("JwtSettings");
            services.Configure<JwtSettings>(appSettingsSection);


            // configure jwt authentication
            var appSettings = appSettingsSection.Get<JwtSettings>();
            var key = Encoding.ASCII.GetBytes(appSettings.Secret);

            services.AddAuthentication(x =>
            
                x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
                x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
            )
          .AddJwtBearer(x =>
          
              x.RequireHttpsMetadata = false;
              x.SaveToken = true;
              x.TokenValidationParameters = new TokenValidationParameters
              
                  ValidateIssuerSigningKey = true,
                  IssuerSigningKey = new SymmetricSecurityKey(key),
                  ValidateIssuer = true,
                  ValidateAudience = true,
                  ValidateLifetime = true,
                  ValidIssuer = appSettings.Issuer,
                  ValidAudience = appSettings.Audience,
                  ClockSkew = TimeSpan.Zero

              ;
              x.Events = new JwtBearerEvents
              
                  OnAuthenticationFailed = context =>
                  
                      if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                      
                          context.Response.Headers.Add("Token-Expired", "true");
                      
                      return Task.CompletedTask;
                  
              ;
          );

登录端点

  [HttpPost]
        public ActionResult Login([FromBody] LoginViewModel user)
        
            if (user == null)
            
                return BadRequest("Invalid client request");
            


            if (user.Email == "user@example.com")
            
                var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(appSettings.Secret));
                var signinCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);

                var tokeOptions = new JwtSecurityToken(
                    issuer: appSettings.Issuer,
                    audience: appSettings.Audience,
                    claims: new List<Claim>(),
                    notBefore: DateTime.UtcNow,
                    expires: DateTime.UtcNow.AddMinutes(30),
                    signingCredentials: signinCredentials
                );

                var tokenString = new JwtSecurityTokenHandler().WriteToken(tokeOptions);

                return Ok(new GenericResponse<string>  Data = tokenString, Message = null, Success = true );
            
            else
            
                return Unauthorized(new GenericResponse<string>  Data = null, Message = "Unauthorized", Success = false );
            

        

【问题讨论】:

有什么更新吗?我的回复对你有帮助吗? @BrandoZhang 是的,有帮助,谢谢,发布了修改。 如果我的回复对您有帮助,请标记为回答。以便其他面临相同问题的人,您可以更轻松地找到答案。 【参考方案1】:

为了让白兰度的回答奏效,我最终这样做了。

            app.Use(async (context, next) =>
            
                string token = context.Session.GetString(config.AccessTokenName);

                if (!string.IsNullOrEmpty(token))
                
                    var jwttoken = new JwtSecurityTokenHandler().ReadJwtToken(token);            
                    var userIdentity = new ClaimsIdentity(jwttoken.Claims);
                    context.User = new ClaimsPrincipal(userIdentity);
                

                await next();

            );

【讨论】:

【参考方案2】:

据我所知,如果您想创建自定义 ClaimsPrincipal,我建议您可以尝试在客户端 asp.net 核心应用程序中使用自定义中间件。

您可以从 Request.Headers 或 Session 中获取令牌(根据您自己的逻辑)。

然后你可以使用 JwtSecurityTokenHandler().ReadJwtToken 来读取令牌。

更多细节,您可以参考以下代码:

将app.use代码添加到startup.cs配置方法中。注意:你应该把它放在use.endpoint之前。

        app.UseRouting();
        app.UseGrpcWeb(); // Must be added between UseRouting and UseEndpoints
        app.UseCookiePolicy();
        app.UseSession();

        app.Use(async (context, next) =>
        
            // you could get from token or get from session. 
            string token = context.Request.Headers["Authorization"];
            if (!string.IsNullOrEmpty(token))
            
                var tok = token.Replace("Bearer ", "");
                var jwttoken = new JwtSecurityTokenHandler().ReadJwtToken(tok);
                var claims = new List<Claim>  /* add claims */ ;
                var userIdentity = new ClaimsIdentity(claims, ClaimTypes.Name);
                context.User = new ClaimsPrincipal(userIdentity);
            

            await next();

        );

那么就可以在客户端操作中直接获取token用户名了:

        var user = User.Identity.Name;

结果:

【讨论】:

谢谢,我试试看。

以上是关于如何使用 JWT Token 管理用户身份?的主要内容,如果未能解决你的问题,请参考以下文章

掌握基于 JWT 实现的 Token 身份认证

前后端分离的Web应用程序中使用Spring Security+Mybatis+JWT非对称加密+动态权限管理:身份验证过滤器

使用JWT实现Token认证

如何以管理员用户身份撤销用户的访问令牌和刷新令牌?在 Oauth2 中使用 JWT

php接口数据安全解决方案

如何通过 vue 路由器和服务器提供的 JWT 令牌管理用户身份验证?