.NET Core6.0配置JWT

发布时间 2023-08-16 14:34:29作者: 初出茅庐子

环境 ASP .NET Core Web API

JWT的一些讲解和与Session的区别俺就不多说了可以去官方文档了解一下

直接上代码简单粗暴(以下操作都是在ASP .NET Core Web API进行操作

第一步:引入一个NuGet包

 

 根据自己.NET版本选择对应的版本号

 

第二步:在appsettings.json配置一些信息

"Authentication": {
    "SecretKey": "你的密钥,长度必面在16位以上,不能泄漏给其它人比如一堆英文字母", 
    "Issuer": "随便输入比如一堆英文字母", //发行人 
    "Audience": "随便输入比如一堆英文字母" //发给谁 受众
  },

第三步:创建一个TokenHelper类

 1 public class TokenHelper
 2     {
 3         private readonly IConfiguration _configuration;
 4         private readonly JwtSecurityTokenHandler _jwtSecurityTokenHandler;
 5         public TokenHelper(IConfiguration configuration, JwtSecurityTokenHandler jwtSecurityTokenHandler)
 6         {
 7             _configuration = configuration;
 8             _jwtSecurityTokenHandler = jwtSecurityTokenHandler;
 9         }
10         /// <summary>
11         /// 创建加密JwtToken
12         /// </summary>
13         /// <param name="user"></param>
14         /// <returns></returns>
15         public string CreateJwtToken<T>(T user)
16         {
17             var signingAlogorithm = SecurityAlgorithms.HmacSha256;
18             var claimList = this.CreateClaimList(user);
19             //Signature
20             //取出私钥并以utf8编码字节输出
21             var secretByte = Encoding.UTF8.GetBytes(_configuration["Authentication:SecretKey"]);
22             //使用非对称算法对私钥进行加密
23             var signingKey = new SymmetricSecurityKey(secretByte);
24             //使用HmacSha256来验证加密后的私钥生成数字签名
25             var signingCredentials = new SigningCredentials(signingKey, signingAlogorithm);
26             //生成Token
27             var Token = new JwtSecurityToken(
28           issuer: _configuration["Authentication:Issuer"], //发布者
29             audience: _configuration["Authentication:Audience"], //接收者
30             claims: claimList, //存放的用户信息
31             notBefore: DateTime.Now, //发布时间
32             expires: System.DateTime.Now.AddMinutes(3), //有效期设置为3分钟
33             signingCredentials //数字签名
34             );
35             //生成字符串token
36             var TokenStr = new JwtSecurityTokenHandler().WriteToken(Token);
37             return TokenStr;
38         }
39 
40       
41         /// <summary>
42         /// 创建包含用户信息的CalimList
43         /// </summary>
44         /// <param name="authUser"></param>
45         /// <returns></returns>
46         private List<Claim> CreateClaimList<T>(T authUser)
47         {
48             //获取当前类型
49             var Class = typeof(T);
50             //存储的载荷信息
51             List<Claim> claimList = new List<Claim>();
52             //GetProperties 获取当前对象的所有属性
53             foreach (var item in Class.GetProperties())
54             {
55                 //忽略
56                 if (item.Name == "UPass")
57                 {
58                     continue;
59                 }
60                 claimList.Add(new Claim(item.Name, Convert.ToString(item.GetValue(authUser))));
61             }
62             //claimList.Add(new Claim("Id", Convert.ToString(authUser)));
63             return claimList;
64         }
65     }

第15行使用泛型集合来接受一个对象参数

第32行设置了一个Token过期时间(注意这个时间可能有些误差比如设置过期时间为1分钟,那么实际过期时间大概在他的3倍左右)

其他东西粘贴即可

第四步:在Program.cs进行配置

 1 var builder = WebApplication.CreateBuilder(args);
 2 
 3 // Add services to the container.
 4 
 5 builder.Services.AddControllers();
 6 // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
 7 builder.Services.AddEndpointsApiExplorer();
 8 builder.Services.AddSwaggerGen(x => {
 9     #region 开启Swagger认证
10     x.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme()
11     {
12 
13         Description = "在下框中输入请求头中需要添加Jwt授权Token:Bearer Token",
14         Name = "Authorization",
15         In = ParameterLocation.Header,
16         Type = SecuritySchemeType.ApiKey,
17         BearerFormat = "JWT",
18         Scheme = "Bearer"
19     });
20 
21     x.AddSecurityRequirement(new OpenApiSecurityRequirement
22                 {
23                     {
24                         new OpenApiSecurityScheme
25                         {
26                             Reference = new OpenApiReference {
27                                 Type = ReferenceType.SecurityScheme,
28                                 Id = "Bearer"
29                             }
30                         },
31                         new string[] { }
32                     }
33                 });
34     #endregion
35 });
36 
37 //JWT认证
38 builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>
39 {
40 
41     //取出私钥
42     var secretByte = Encoding.UTF8.GetBytes(builder.Configuration["Authentication:SecretKey"]);
43     options.TokenValidationParameters = new TokenValidationParameters()
44     {
45         //验证发布者
46         ValidateIssuer = true,
47         ValidIssuer = builder.Configuration["Authentication:Issuer"],
48         //验证接收者
49         ValidateAudience = true,
50         ValidAudience = builder.Configuration["Authentication:Audience"],
51         //验证是否过期
52         ValidateLifetime = true,
53         //验证私钥
54         IssuerSigningKey = new SymmetricSecurityKey(secretByte)
55     };
56 });

第9至34行是在Swagger中加一个填写Token的按钮其中13至19是按钮里面显示的信息如下

 点击按钮后出现以下界面

 接下来在中间件中配置

 到这里已经完成了百分之九十

最后一步:创建一个控制器使用依赖注入将我们的TokenHelper注入进来

 编写一个登录的方法

 1         [HttpPost]
 2         [AllowAnonymous]
 3         public IActionResult GetLogin(LoginDto m)
 4         {
 5             ApiResult apiResult = new ApiResult();
 6             var obj = UserService.GetLogin(m);
 7 
 8             if(obj!=null)
 9             {
10                 apiResult.data = obj;
11                 apiResult.message = "登录成功!";
12                 apiResult.code = "200";
13                 var token = TokenHelper.CreateJwtToken(m);
14                 HttpContext.Response.Headers["token"] = token;
15                 Response.Headers["Access-Control-Expose-Headers"] = "token";
16                 return Ok(apiResult);
17             }
18             apiResult.data = null;
19             apiResult.code = "500";
20             apiResult.message = "登录有误!";
21             return Ok(apiResult);
22         } 
[AllowAnonymous]必须加上,它的主要作用就是无需身份验证进行操作
然后这里的第13到15行就是重中之重一定不要忘记写
第13行我们将我们查询到的用户信息当作参数调用我们TokenHelper中的方法创建一个JWT Token
第14行将生成的 JWT Token 存储在 HTTP 响应的头部中,使用键名 "token"。  这样,客户端在收到响应后可以从响头中获取该 Token。如下

 第15行设置了一个名为 "Access-Control-Expose-Headers" 的响应头,其值为 "token"。这是为了指定客户端在跨域请求时,可以访问到响应头中的 “token” 值。默认情况下,许多浏览器会限制客户端对某些响应头的访问,例如包含敏感信息。通过设置 "Access-Control-Expose-Headers" 头部,允许客户端访问指定的响应头部信息。

到这里已经大功告成了,已经可以在swagger中进行测试了,流程就是在没有登录的情况下,调用接口状态码都是401

解决方法就是先登录拿到Token解锁,这样就可以调用其他的方法了!!!