- A+
所属分类:.NET技术
前言
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