一. Service层安装依赖包:Authtication.JwtBearer
![](https://ichistudio.cn/wp-content/uploads/2023/09/图片-5.png)
二. 编写生成Token逻辑
Interface
C#
public interface IJWTService
{
Task<string> GetToken(UserRes user);
}
Services
C#
public class JWTService : IJWTService
{
//通过JWT注入配置
private readonly JWTTokenOptions _JWTTokenOptions;
public JWTService(IOptionsMonitor<JWTTokenOptions> jwtTokenOptions)
{
_JWTTokenOptions = jwtTokenOptions.CurrentValue;
}
public async Task<string> GetToken(UserRes user)
{
var result = await Task.Run(() =>
{
var claims = new[]
{
new Claim("Id",user.Id),
new Claim("NickName",user.NickName),
new Claim("Name",user.Name),
new Claim("UserType",user.UserType.ToString()),
new Claim("Image",user.Image==null?"":user.Image)
};
//需要加密:需要加密key:
//Nuget引入:Microsoft.IdentityModel.Tokens
SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_JWTTokenOptions.SecurityKey));
SigningCredentials creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
//Nuget引入:System.IdentityModel.Tokens.Jwt
JwtSecurityToken token = new JwtSecurityToken(
issuer: _JWTTokenOptions.Issuer,
audience: _JWTTokenOptions.Audience,
claims: claims,
expires: DateTime.Now.AddMinutes(10),//10分钟有效期
notBefore: null,
signingCredentials: creds);
string res = new JwtSecurityTokenHandler().WriteToken(token);
return res;
});
return result;
}
}
Program
C#
//注入appsettings中的配置
builder.Services.Configure<JWTTokenOptions>(builder.Configuration.GetSection("JWTTokenOptions"));
三. Token验证逻辑
Program
C#
#region JWT校验
{
JWTTokenOptions tokenOptions = new JWTTokenOptions();
builder.Configuration.Bind("JWTTokenOptions", tokenOptions);
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)//Scheme
.AddJwtBearer(options => //这里是配置的鉴权的逻辑
{
options.TokenValidationParameters = new TokenValidationParameters
{
//JWT有一些默认的属性,就是给鉴权时就可以筛选了
ValidateIssuer = true,//是否验证Issuer
ValidateAudience = true,//是否验证Audience
ValidateLifetime = true,//是否验证失效时间
ValidateIssuerSigningKey = true,//是否验证SecurityKey
ValidAudience = tokenOptions.Audience,//
ClockSkew = TimeSpan.FromSeconds(0),//设置token过期后多久失效,默认过期后300秒内仍有效
ValidIssuer = tokenOptions.Issuer,//Issuer,这两项和前面签发jwt的设置一致
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenOptions.SecurityKey))//拿到SecurityKey
};
});
}
#endregion
四. WebAPI配置JWT认证和授权逻辑,以及补充配置文件
统一定义返回结果:ResultHelper
C#
public class ResultHelper
{
public static ApiResult Successs(object data)
{
return new ApiResult() { IsSuccess = true, Msg = string.Empty, Result = data };
}
public static ApiResult Error(string error)
{
return new ApiResult() { IsSuccess = false, Msg = error, Result = null };
}
}
Controller控制器Login
C#
[Route("api/[controller]/[action]")]
[ApiController]
public class Login : ControllerBase
{
//通过构造函数注入服务
private readonly ILogger<Login> _logger;
private readonly IUser _user;
private readonly IJWTService _jwtService;
public Login(ILogger<Login> logger, IUser user, IJWTService jWTService)
{
_logger = logger;
_user = user;
_jwtService = jWTService;
}
//请求
[HttpPost]
public async Task<ApiResult> GetToken([FromForm] LoginReq req)
{
//模型验证
if (ModelState.IsValid)
{
UserRes userRes = await _user.GetUser(req);
if (userRes == null)
{
return ResultHelper.Error("账号不存在,用户名或密码错误");
}
_logger.LogInformation("登录");
return ResultHelper.Successs(await _jwtService.GetToken(userRes));
}
else
{
return ResultHelper.Error("参数错误");
}
}
}