生成Jwt认证用于角色的认证权限(加密)以后与RBAC使用
一、首先,创建用户表创建表名如下:
/// <summary>
/// 用户ID
/// </summary>
[Key]
public int UserId { get; set; }
/// <summary>
/// 用户名
/// </summary>
public string ? UserName { get; set; }
/// <summary>
/// 密码
/// </summary>
public string? Password { get; set; }
/// <summary>
/// 秘钥 用于储存Jwt生成的Token
/// </summary>
public string?Token { get; set; }
二、:下载JWT的NuGet包
Microsoft.AspNetCore.Authentication.JwtBearer
三、在Program中写入如下代码
因为是对称加密,所以封装一个秘钥,以便调用
public class Const
{
//注意 jwtkey 长度要大于20 否者会报错
public static string jwtkey = "qwertyuiopasdfghjklzxcvbnm";
}
注意 :Program 为了减少文件的冲突性所以要在秘钥类下边再次创建个类,存放中间件等
public class Const
{
public static string jwtkey = "qwertyuiopasdfghjklzxcvbnm";
}
public class Program
{
public static void Main(string[] args)
{
此处省略注入上下文类和注入其他代码......
//身份认证
//AddAuthentication:添加身份验证
//JwtBearerDefaults.AuthenticationScheme 是 JWT Bearer 认证的默认方案名称。
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(builder =>
{
//TokenValidationParameters 是一个用于验证 JWT 令牌的参数对象
builder.TokenValidationParameters = new TokenValidationParameters
{
//验证
ValidateActor = false, //验证令牌的 “actor”(操作者)声明。
ValidateIssuer = false, //验证令牌的 “issuer”(颁发者)声明。
ValidateAudience = false, //验证令牌的 “audience”(受众)声明。
ValidIssuer = "2013A",//令牌颁发机构的标识符
ValidAudience = "2013A", //令牌的受众群体。
//使用指定的密钥来验证令牌的签名
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Const.jwtkey))//对称密钥,通过将字符串编码为UTF8字节生成密钥
};
//Events:属性,处理认证过程中不同阶段时间的回调方法
//JwtBearerEvents:一个包含各种事件委托的类(通过实例并通过Events属性赋值来为不同的事件操作提供自定义的逻辑)
builder.Events = new JwtBearerEvents
{
//OnMessageReceived:事件、来自定义再接收消息时处理的jwt令牌的逻辑
OnMessageReceived = (x) =>
{
//从请求cookie中获取并验证JWT令牌
var cooke = x.HttpContext.Request.Cookies["token"];
x.Token = cooke;
return Task.CompletedTask;
}
};
});
此处省略中间件其他代码......
四、在Program中写入认证和授权中间件(注意:先认证后授权)
app.UseAuthentication(); //用户认证
app.UseAuthorization(); //用户授权
五、在控制器登录方法中生成Token并存入登录表中的Token 字段中
/// <summary>
/// 登录
/// </summary>
/// <param name="UserName">用户名</param>
/// <param name="UserPassword">密码</param>
/// <returns></returns>
[HttpGet]
[AllowAnonymous] //允许匿名访问
public IActionResult UserLogin(string? UserName, string? UserPassword)
{
//用户登录
var userlist = rbac.UserLogin(UserName, UserPassword);
//把写进去的密钥改变成计算机的二进制
//Encoding:用来处理不同语言之间的格式
var ketBytes = Encoding.UTF8.GetBytes(Const.jwtkey);
//实例化,最终生成token
JwtSecurityTokenHandler handler = new JwtSecurityTokenHandler();
//令牌描述
var tokenDescriptor = new SecurityTokenDescriptor
{
//过期时间
Expires= DateTime.Now.AddDays(1),
//Subject:主题 获取到用户id和用户名
Subject = new ClaimsIdentity(new[] {new Claim("id", userlist.UserId.ToString()),new Claim("name", UserName) }) { },
//SigningCredentials:签名凭据(HmacSha256算法)进行加密
SigningCredentials = new SigningCredentials(new SymmetricSecurityKey(ketBytes),SecurityAlgorithms.HmacSha256)
};
//CreateJwtSecurityToken 是 JwtSecurityTokenHandler 类中的一个方法,用于创建 JWT 安全令牌。
JwtSecurityToken token = handler.CreateJwtSecurityToken(tokenDescriptor);
var jwttoken = handler.WriteToken(token);
userlist.UserToken = jwttoken;
Response.Cookies.Append("token", userlist.UserToken);
return Ok(userlist);
}
然后登录发现Token被赋值一大长串秘钥,到此生成Jwt完毕