河岸青青 发表于 2023-9-26 10:53:45

WebApi中添加Jwt鉴权

前言

JSON Web Token(JWT)是一个非常轻巧的规范。这个规范允许我们使用 JWT 在用户和服务器之间传递安全可靠的信息。一个 JWT 实际上就是一个字符串,它由三部分组成,头部、载荷与签名。前两部分需要经过 Base64 编码,后一部分通过前两部分 Base64 编码后再加密而成。针对前后端分离的项目,大多是通过 token 进行身份认证来进行交互,今天将介绍一种简单的创建 和验证token 的方式 。

项目介绍

项目框架:.NET Core 3.1
项目依赖:

[*]Swashbuckle.AspNetCore
[*]JWT
项目架构:

项目核心代码

JWT帮助类
/// <summary>
    /// JWT获取和验证帮助类
    /// </summary>
    public class JwtHelper
    {
      /// <summary>
      /// 日志
      /// </summary>
       private static Logger_logger = new Logger();

      /// <summary>
      /// 私钥appsettings.json中配置
      /// </summary>
      private static string secret =ConfigHelper.GetSectionValue("TokenSecret");

      /// <summary>
      /// 生成JwtToken
      /// </summary>
      /// <param name="payload">不敏感的用户数据</param>
      /// <returns></returns>
      public static string SetJwtEncode(Dictionary<string, object> payload)
      {
            try
            {
                IJwtAlgorithm algorithm = new HMACSHA256Algorithm();
                IJsonSerializer serializer = new JsonNetSerializer();
                IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                IJwtEncoder encoder = new JwtEncoder(algorithm, serializer, urlEncoder);

                var token = encoder.Encode(payload, secret);
                return token;
            }
            catch (System.Exception ex)
            {
                _logger.Error(ex.Message);
                return null;
            }

      }

      /// <summary>
      /// 根据jwtToken获取实体
      /// </summary>
      /// <param name="token">jwtToken</param>
      /// <returns></returns>
      public static LoginUserInfo GetJwtDecode(string token)
      {
            try
            {
                IJsonSerializer serializer = new JsonNetSerializer();
                IDateTimeProvider provider = new UtcDateTimeProvider();
                IJwtValidator validator = new JwtValidator(serializer, provider);
                IBase64UrlEncoder urlEncoder = new JwtBase64UrlEncoder();
                IJwtDecoder decoder = new JwtDecoder(serializer, urlEncoder);
                //IJwtDecoder decoder = new JwtDecoder(serializer, validator, urlEncoder);
                var userInfo = decoder.DecodeToObject<LoginUserInfo>(token, secret, verify: true);//token为之前生成的字符串
                return userInfo;
            }
            catch (System.Exception ex)
            {
                _logger.Error(ex.Message);
                return null;
            }

      }

    }过滤器Filter
/// <summary>
    /// 授权认证
    /// </summary>
    public class AuthorizeFilter : Attribute, IActionFilter
    {

      public void OnActionExecuted(ActionExecutedContext context)
      {

      }

      public void OnActionExecuting(ActionExecutingContext context)
      {
            var controller = context.RouteData.Values["controller"].ToString();
            //var action = context.RouteData.Values["action"].ToString();
            if (controller == "User" || controller == "Jwt")
            {
                //登录接口不验证
            }
            else
            {
                var authHeader = context.HttpContext.Request.Headers["Authorization"];
                if (string.IsNullOrWhiteSpace(authHeader))
                {
                  //此接口必须携带token访问!
                  context.Result = new JsonResult(new OperationResult(OperationResultType.Error, "此接口必须携带token访问,请登录携带Token访问"));
                }
                else //字段值不为空
                {
                  authHeader = authHeader.ToString().Replace("Bearer", "").Trim();//去掉Bearer字串
                  if (authHeader == "")
                  {
                        context.Result = new JsonResult(new OperationResult(OperationResultType.Error, "token验证失败:您没有权限调用此接口,请登录重新获取Token"));
                  }
                  else
                  {
                        LoginUserInfo LoginInfo = JwtHelper.GetJwtDecode(authHeader);
                        if (LoginInfo != null)
                        {
                            context.Result = new JsonResult(new OperationResult(OperationResultType.Error, "Token验证失败"));
                        }
                        string UserName = LoginInfo.username;
                        string PassWord = LoginInfo.pwd;
                        string ExpireTimeStamp = LoginInfo.exp;
                        //var cacheToken = Cache.Get(UserName);
                        if (isTokenExpire(ExpireTimeStamp)) //这里应该验证有效期
                        {
                            context.Result = new JsonResult(new OperationResult(OperationResultType.Error, "token验证失败:您没有权限调用此接口,请登录重新获取Token"));
                        }
                  }

                }
            }
      }

      /// <summary>
      /// 时间戳字符串
      /// </summary>
      /// <param name="timestampstr"></param>
      /// <returns></returns>
      private bool isTokenExpire(string timestampstr)
      {
            try
            {
                double timestamp = double.Parse(timestampstr);
                System.DateTime startTime = TimeZone.CurrentTimeZone.ToLocalTime(new System.DateTime(1970, 1, 1));//当地时区
                var expireTime = startTime.AddSeconds(timestamp);
                if (expireTime > DateTime.Now)
                {
                  return false;//未过期
                }
                else
                {
                  return true;//已过期
                }
            }
            catch (Exception ex)
            {
                return true;
            }
      }

    }测试验证

Swagger页面

登录获取Token

未携带token访问接口

源码获取

关注公众号,后台回复关键字:JwtApiDemo

来源:https://www.cnblogs.com/wml-it/archive/2023/09/26/17728594.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!
页: [1]
查看完整版本: WebApi中添加Jwt鉴权