.NET 6 项目中如何使用JWT授权

一、打开nuget,搜索JWT,安装最新版到对应的使用层即可 1

1、 JWT依赖包

2、 JWT的认证授权扩展包、Microsoft.AspNetCore.Authentication.JwtBearer版本

在这里插入图片描述
(注:这里使用的是 .NET 6,所以 JWT的认证授权扩展包安装的版本是6开头的)

二、创建JWT相关的帮助类

在这里插入图片描述

1、JwtHelper帮助类

public static class JwtHelper
{
    /// <summary>
    /// 生成token令牌
    /// </summary>
    /// <param name="claimInfo"></param>
    /// <param name="tokenManagement"></param>
    /// <returns></returns>
    public static string CreateToken(Claim[] claimInfo, TokenManagement tokenManagement)
    {
      	//1、获取TokenManagement类中的Secret字符串
		var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(tokenManagement.Secret));
		//2、key加密方式
		var credentials = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
		//3、生成token的时间
		var notTime = DateTimeHelper.GetThisDateTime(); //开始时间
		//4、token过期时间
		var expiresTime = notTime.AddMinutes(tokenManagement.AccessExpiration);    //到期时间
		//5、生成token的配置信息
		var jwtToken = new JwtSecurityToken(tokenManagement.Issuer, tokenManagement.Audience, claimInfo, notTime, expiresTime, credentials);

        string token = new JwtSecurityTokenHandler().WriteToken(jwtToken);

        return token;
    }

    /// <summary>
    /// 获取请求上下文Claims中的UserId
    /// </summary>
    /// <param name="httpContext">请求上下文</param>
    /// <returns></returns>
    public static string GetUserId(HttpContext httpContext)
    {
        string userId = "";
        if (httpContext.User is null)
            return userId;
        if (!httpContext.User.Claims.Any())
            return userId;

        var claim = httpContext.User.Claims.FirstOrDefault(e => e.Type == ClaimTypes.Sid);
        if (claim is null)
            return userId;

        userId = claim.Value;
        return userId;
    }

    /// <summary>
    /// 获取请求上下文Claims中的Name名称
    /// </summary>
    /// <param name="httpContext">请求上下文</param>
    /// <returns></returns>
    public static string GetName(HttpContext httpContext)
    {
        string name = "";
        if (httpContext.User is null)
            return name;
        if (!httpContext.User.Claims.Any())
            return name;

        var claim = httpContext.User.Claims.FirstOrDefault(e => e.Type == ClaimTypes.Name);
        if (claim is null)
            return name;

        name = claim.Value;
        return name;
    }

    /// <summary>
    /// 解析token获取JwtSecurityToken对象
    /// </summary>
    /// <param name="token">token</param>
    /// <returns></returns>
    public static JwtSecurityToken GetSecurityToken(string token)
    {
        token = GetRemoveBearerToken(token);

        //解析token
        JwtSecurityToken jwtToken = new JwtSecurityTokenHandler().ReadJwtToken(token);

        return jwtToken;
    }

    /// <summary>
    /// 获取token中存储的信息
    /// </summary>
    /// <param name="httpContext">http数据上下文</param>
    /// <returns></returns>
    public static TokenPayload GetTokenPayload(HttpContext httpContext)
    {
        var token = GetRemoveBearerToken(httpContext.Request.Headers["Authorization"].ToString());

        //解析token
        JwtSecurityToken jwtToken = new JwtSecurityTokenHandler().ReadJwtToken(token);
        //获取token中的payload信息
        TokenPayload tokenPayload = new TokenPayload()
        {
            Id = Convert.ToInt32(jwtToken.Payload[ClaimTypes.Sid]),
            Email = jwtToken.Payload[ClaimTypes.Email].ToString(),
            UserName = jwtToken.Payload[ClaimTypes.Surname].ToString(),
            Name = jwtToken.Payload[ClaimTypes.Name].ToString(),
            Role = jwtToken.Payload[ClaimTypes.Role].ToString(),
        };
        
        return tokenPayload;
    }

    /// <summary>
    /// 获取token中存储的信息
    /// </summary>
    /// <param name="token">token令牌</param>
    /// <returns></returns>
    public static TokenPayload GetTokenPayload(string token)
    {
        token = GetRemoveBearerToken(token);

        //解析token
        JwtSecurityToken jwtToken = new JwtSecurityTokenHandler().ReadJwtToken(token);
        //获取token中的payload信息
        TokenPayload tokenPayload = new TokenPayload()
        {
            Id = Convert.ToInt32(jwtToken.Payload[ClaimTypes.Sid]),
            Email = jwtToken.Payload[ClaimTypes.Email].ToString(),
            UserName = jwtToken.Payload[ClaimTypes.Surname].ToString(),
            Name = jwtToken.Payload[ClaimTypes.Name].ToString(),
        };
        if (jwtToken.Payload[ClaimTypes.Role] != null)
            tokenPayload.Role = jwtToken.Payload[ClaimTypes.Role].ToString();

        return tokenPayload;
    }

    /// <summary>
    /// 获取去除字符串开头Bearer的token令牌
    /// </summary>
    /// <param name="token">token令牌</param>
    /// <returns></returns>
    /// <exception cref="ArgumentNullException"></exception>
    public static string GetRemoveBearerToken(string token)
    {
        if (token.IsNullOrEmpty())
            throw new ArgumentNullException("传入的token为空!");

        if (token.StartsWith("Bearer "))
            return token.Replace("Bearer ", "");

        return token;
    }
}

2、创建TokenManagement类,存储JWT相关的配置信息

/// <summary>
/// 存储Jwt配置信息
/// </summary>
public class TokenManagement
{
    /// <summary>
    /// 令牌密钥
    /// </summary>
    [JsonProperty("secret")]
    public string Secret { get; set; } = null!;

    /// <summary>
    /// 颁发者
    /// </summary>
    [JsonProperty("issuer")]
    public string? Issuer { get; set; }

    /// <summary>
    /// 接收者
    /// </summary>
    [JsonProperty("audience")]
    public string? Audience { get; set; }

    /// <summary>
    /// Token令牌过期时间(分钟)
    /// </summary>
    [JsonProperty("accessExpiration")]
    public int AccessExpiration { get; set; }

    /// <summary>
    /// Token刷新令牌过期时间(分钟)
    /// </summary>
    [JsonProperty("refreshExpiration")]
    public int RefreshExpiration { get; set; }
}

3、创建TokenPayload类,用于存储我们的payload信息

/// <summary>
/// 存储、解析生成Token要用到的信息
/// </summary>
public class TokenPayload
{
    /// <summary>
    /// 编号
    /// </summary>
    public long Id { get; set; }

    /// <summary>
    /// 名称
    /// </summary>
    public string? Name { get; set; }

    /// <summary>
    /// 邮箱
    /// </summary>
    public string? Email { get; set; }

    /// <summary>
    /// 用户名
    /// </summary>
    public string? UserName { get; set; }

    /// <summary>
    /// 角色
    /// </summary>
    public string? Role { get; set; }

}

三、appsestting.json配置文件,配置JWT过期等密钥信息

 //JwtTokenManagement参数
 "TokenManagement": {
   "secret": "8630EAA6-CB86-413F-D925-08DC525AFD88", //"密钥",
   "issuer": "longNight", //签发
   "audience": "longNightClient", //接收
   "accessExpiration": 120, //过期分钟数,2小时过期
 }

四、在Program中配置JWT相关信息

#region Jwt配置

//读取Jwt配置信息
var jwtSection = builder.Configuration.GetSection("TokenManagement");
//Jwt配置信息,注入配置中
builder.Services.Configure<TokenManagement>(jwtSection);

TokenManagement tokenManagement = jwtSection.Get<TokenManagement>();

//Jwt鉴权配置
builder.Services.AddAuthorization(options => { }).AddAuthentication(options =>
    {
        //2.1【认证】、core自带官方JWT认证
        // 开启Bearer认证
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    }).AddJwtBearer(options =>
    {
        options.RequireHttpsMetadata = false;
        options.SaveToken = true;
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuerSigningKey = true,    //是否验证SecurityKey
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(tokenManagement.Secret)),    //这里的key要进行加密
            //验证发布者Issuer
            ValidateIssuer = true,
            ValidIssuer = tokenManagement.Issuer,   //Token颁发机构
            //验证接收者
            ValidateAudience = true,
            ValidAudience = tokenManagement.Audience,   //颁发给谁   
            ValidateLifetime = true,    //验证token过期时间
            ClockSkew = TimeSpan.FromSeconds(30),    //时钟缓冲相位差
            RequireExpirationTime = true,   //token需要设置过期时间
        };
        options.Events = new JwtBearerEvents
        {
            OnAuthenticationFailed = context =>
            {
                // 如果过期,则把<是否过期>添加到,返回头信息中
                if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                {
                    context.Response.Headers.Add("Token-Expired", "true");
                }
                return Task.CompletedTask;
            }
        };
    });

#endregion

  1. 记录学习时刻 ↩︎

  • 10
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值