一篇文章教你怎么使用JWT

191 阅读2分钟

首先先创建一个.net core的api 我这里使用的是 .net6 core 这里就不做过多创建了

我这里创建了一个Extension类,主要的作用用于 配置 WebApplication WebApplicationBuilder 相当于给单拿出来了

public static  class Extension
    {
         public static void WebApplicationBuilder(WebApplicationBuilder builder)
        {

            //注册jwt身份验证服务
            builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                              .AddJwtBearer(options =>
                              {
                                  options.TokenValidationParameters = new TokenValidationParameters()
                                  {
                                      //验证发布者
                                      ValidateIssuer = true,
                                      ValidIssuer = JwtSetting.Issur,
                                      //验证接收者
                                      ValidateAudience = true,
                                      ValidAudience = JwtSetting.Audience,
                                      //验证是否过期
                                      ValidateLifetime = true,
                                      //验证私钥
                                      IssuerSigningKey = new SymmetricSecurityKey(
                                          Encoding.UTF8.GetBytes(JwtSetting.SecretKey)),
                                      //验证时间 秒钟  30秒验证一次
                                      ClockSkew = TimeSpan.FromSeconds(30),
                                      AudienceValidator = (m, n, z) =>
                                      {
                                          //匹配token接收者是否存在
                                          return m != null && m.FirstOrDefault().StartsWith(JwtSetting.Audience);
                                      },
                                  };
                                  options.Events = new JwtBearerEvents
                                  {
                                      //此处为权限验证失败后触发的事件
                                      OnChallenge = context =>
                                      {
                                          //此处代码为终止.Net Core默认的返回类型和数据结果,这个很重要,必须
                                          context.HandleResponse();
                                          //自定义返回的数据类型
                                          context.Response.ContentType = "application/json";
                                          //自定义返回状态码,默认为401
                                          context.Response.StatusCode = StatusCodes.Status401Unauthorized;
                                          return Task.FromResult(0);
                                      }
                                  };

                              });

            builder.Services.AddSwaggerGen(c =>
            {
                //jwt鉴权在swagger中的应用
                c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
                {
                    Description = "请输入toke,格式为 Bearer xxxxxxxxxx(注意中间必须有空格)",
                    Name = "Authorization",
                    In = ParameterLocation.Header,
                    Type = SecuritySchemeType.ApiKey,
                    BearerFormat = "JWT",
                    Scheme = "Bearer"
                });
                c.AddSecurityRequirement(new OpenApiSecurityRequirement
                    {
                        {
                            new OpenApiSecurityScheme{
                                Reference = new OpenApiReference {
                                            Type = ReferenceType.SecurityScheme,
                                            Id = "Bearer"}
                           },new string[] { }
                        }
                    });
            });

            //添加跨域策略
            builder.Services.AddCors(options =>
            {
                options.AddPolicy("CrossDomain", opt => opt.AllowAnyOrigin().AllowAnyHeader().AllowAnyMethod().WithExposedHeaders("X-Pagination"));
            });

            builder.Services.AddTransient<ResultJson>();


        public static void WebApplication(WebApplication app)
        {
            JwtSetting.Issur = app.Configuration["JwtSetting:Issur"];
            JwtSetting.Audience = app.Configuration["JwtSetting:Audience"];
            JwtSetting.SecretKey = app.Configuration["JwtSetting:SecretKey"];
            JwtSetting.ExpireSeconds = app.Configuration["JwtSetting:ExpireSeconds"];
        }
    }

找到Program.cs 将类拿过来直接调用即可

image.png

在定义一个 JwtHelper 类去获取 token (代码中有注释)

 public static string JwtToken(string nameID,string role)
        {
            #region Claim 属性说明
            /**  Claim 属性说明
            * jti  : 鉴权id,防止重复
            * iat  : 鉴权颁发时间
            * nbf  : 暂时不知道是干啥的时间
            * exp  : 鉴权过期时间
            * iss  : 鉴权颁发人,主体
            * aud  : 鉴权的接收者
            * role :鉴权的角色
            */
            #endregion

            var claims = new[]
            {

                 /*
                * 特别重要:
                1、这里将用户的部分信息,比如 uid 存到了Claim 中,如果你想知道如何在其他地方将这个 uid从 Token 中取出来,
                   请看下边的SerializeJwt() 方法,或者在整个解决方案,搜索这个方法,看哪里使用了!
                2、你也可以研究下 HttpContext.User.Claims ,具体的你可以看看 Policy/PermissionHandler.cs 类中是如何使用的。
                */
                new Claim(JwtRegisteredClaimNames.Jti, nameID),
                new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
                 //new Claim(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
                //这个就是过期时间,目前是过期2分钟,可自定义,注意JWT有自己的缓冲过期时间
                new Claim (JwtRegisteredClaimNames.Exp, $"{new DateTimeOffset(DateTime.Now.AddMinutes(2)).ToUnixTimeSeconds()}"),
                new Claim(JwtRegisteredClaimNames.Iss,JwtSetting.Issur),
                new Claim(JwtRegisteredClaimNames.Aud,JwtSetting.Audience),
                new Claim (ClaimTypes.Role,role)

                //new Claim(JwtRegisteredClaimNames.Iat, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}"),
                //new Claim(JwtRegisteredClaimNames.Nbf, $"{new DateTimeOffset(DateTime.Now).ToUnixTimeSeconds()}") ,
                ////这个就是过期时间,目前是过期2分钟,可自定义,注意JWT有自己的缓冲过期时间
                //new Claim (JwtRegisteredClaimNames.Exp, $"{new DateTimeOffset(DateTime.Now.AddMinutes(2)).ToUnixTimeSeconds()}"),
                //new Claim(JwtRegisteredClaimNames.Iss, Issuer),
                //new Claim(JwtRegisteredClaimNames. Aud, Audience + DateTime.Now.ToString()),
                //new Claim(ClaimTypes.Role, role) //添加访问权限

                //new Claim(ClaimTypes.Name ,name),
                //new Claim (ClaimTypes.Role ,role),
                //new Claim(JwtRegisteredClaimNames.Jti,name),
            };
            //取私钥并以uft8编码输出
            var secretKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(JwtSetting.SecretKey));
      
            //使用非对称算法进行对私钥进行加密
   
            //生成 Credentials
            var signingCredentials = new SigningCredentials(secretKey, SecurityAlgorithms.HmacSha256);
            var Token = new JwtSecurityToken(
                   issuer: JwtSetting.Issur,                          //发布者
                   audience: JwtSetting.Audience,                    //接收者
                   claims: claims,                                   //存放的用户信息
                   notBefore: DateTime.Now,                       //发布时间
                   expires: DateTime.Now.AddMinutes(2),           //有效期设置为2分钟
                   signingCredentials: signingCredentials                      //数字签名
            );
            string tokenStr = new JwtSecurityTokenHandler().WriteToken(Token);
            return tokenStr;
        }

将获取的Token 输入在Vlue 中,不过要切记 格式 Bearer +token

image.png 最好是一个简单的调用截图,具体的效果,大家可以自己练习一下

image.png