什么是JWT(Json-Web-Token)?JWT的用途和上风是什么?讲解+实战,一篇文章 ...

打印 上一主题 下一主题

主题 797|帖子 797|积分 2391

1、什么是JWT

最近刚刚启动搭建一个会员支付体系的项目,单点登任命到JWT来认证,借此机会来谈一谈JWT的相关知识,后续也会分享项目中的相关技术点,各人点赞关注哦~~~
1.1、JWT的介绍

官方表明:JSON Web Token (JWT) 是一种开放标准 (RFC 7519),它界说了一种紧凑且独立的方式,用于在各方之间以 JSON 对象的情势安全地传输信息。此信息可以验证和信任,因为它是颠末数字署名的。JWT 可以利用密钥(利用 HMAC算法)或利用 RSA 或 ECDSA 的公钥/私钥对进行署名。

简单来说,JWT就是用来判断某种信息是否可以被信任的一种署名json
1.2、JWT的利用场景


  • 身份验证(Authentication):JWT 可以被用作用户登录的身份验证凭证。当用户乐成登录后,服务端可以天生一个包含用户信息的 JWT,并将其返回给客户端。以后,客户端在每次请求时都会携带这个 JWT,服务端通过验证 JWT 的署名来确认用户的身份。
  • 授权(Authorization):在用户登录后,服务端可以天生包含用户角色、权限等信息的 JWT,并在用户每次请求时进行验证。通过解析 JWT 中的声明信息,服务端可以判断用户是否有权限实行特定的操作或访问特定的资源。
  • 信息交换(Information Exchange):由于 JWT 的声明信息可以被加密,因此可以安全地在用户和服务器之间传递信息。这在分布式体系中非常有用,因为可以确保信息在各个环节中的安全传递。
  • 单点登录(Single Sign-On):JWT 可以被用于支持单点登录,使得用户在多个应用之间只需要登录一次即可利用多个应用,从而进步用户体验。
1.3、JWT的上风


  • 无状态:JWT 的验证是基于密钥的,因此它不需要在服务端存储用户信息。这使得 JWT 可以作为一种无状态的身份认证机制。
  • 跨语言支持:JWT 的标准化和简单性质使得它可以在多种语言宁静台之间利用。
  • 安全性高:由于 JWT 的载荷可以进行加密处理,因此 JWT 能够保证数据的安全传输。同时,JWT 的署名机制也能够保证数据的完整性和真实性。
2、JWT的结构


JWT由Header+Payload+Signature三部分组成 

Header

JWT 的头部通常由两部分组成,分别是令牌类型(typ)和加密算法(alg)。一样平常环境下,头部会接纳 Base64 编码。 
  1. {
  2.   "alg": "HS256",
  3.   "typ": "JWT"
  4. }
复制代码
Payload

JWT 的载荷也称为声明信息,包含了一些有关实体(通常是用户)的信息以及其他元数据。通常包括以下几种声明:


  • Registered Claims:这些声明是预界说的,包括 iss(发行者)、sub(主题)、aud(受众)、exp(过期时间)、nbf(见效时间)、iat(发布时间)和 jti(JWT ID)等。
  • Public Claims:这些声明可以自界说,但需要注意避免与注册声明的名称辩论。
  • Private Claims:这些声明是保留给特定的应用步伐利用的,不会与其他应用步伐辩论。
   注意:Payload中一定不要存放敏感或重要信息,如密码等
  1. {
  2.   "sub": "666666",
  3.   "name": "warriors",
  4.   "admin": true
  5. }
复制代码
 Signature

JWT 的署名是由头部、载荷和密钥共同天生的。它用于验证 JWT 的真实性和完整性。一样平常环境下,署名也会接纳 Base64 编码。
例如,如果要利用 HMAC SHA256 算法,将按以下方式创建署名:
  1. HMACSHA256(
  2.   base64UrlEncode(header) + "." +
  3.   base64UrlEncode(payload),
  4.   secret)
复制代码
3、SpringMVC架构中的JWT利用示例

3.1、引入Maven依赖

  1. <dependency>
  2.    <groupId>io.jsonwebtoken</groupId>
  3.    <artifactId>jjwt-api</artifactId>
  4.    <version>0.11.5</version>
  5. </dependency>
  6. <dependency>
  7.    <groupId>io.jsonwebtoken</groupId>
  8.    <artifactId>jjwt-impl</artifactId>
  9.    <version>0.11.5</version>
  10.    <scope>runtime</scope>
  11. </dependency>
  12. <dependency>
  13.    <groupId>io.jsonwebtoken</groupId>
  14.    <artifactId>jjwt-jackson</artifactId>
  15.    <version>0.11.5</version>
  16.    <scope>runtime</scope>
  17. </dependency>
复制代码
3.2 、编写JWT工具类,实现JWT天生,JWT校验等功能
 


  1. public class JWTUtil {
  2.     // JWT过期时间
  3.     public static final long JWT_TTL = 60 * 60 * 1000L * 24 * 14;
  4.     // JWT_KEY为服务器私钥,注意保密
  5.     public static final String JWT_KEY = "aBcDeFgHdkfajdja50490fjaifeja4ief";
  6.     public static String getUUID() {
  7.         return UUID.randomUUID().toString().replaceAll("-", "");
  8.     }
  9.     /**
  10.      * 生成JWT
  11.      * @param subject 用户唯一标识ID
  12.      * @return
  13.      */
  14.     public static String createJWT(String subject) {
  15.         JwtBuilder builder = getJwtBuilder(subject, null, getUUID());
  16.         return builder.compact();
  17.     }
  18.     private static JwtBuilder getJwtBuilder(String subject, Long ttlMillis, String uuid) {
  19.         // 自行选择加密算法
  20.         SignatureAlgorithm signatureAlgorithm = SignatureAlgorithm.HS256;
  21.         SecretKey secretKey = generalKey();
  22.         long nowMillis = System.currentTimeMillis();
  23.         Date now = new Date(nowMillis);
  24.         if (ttlMillis == null) {
  25.             ttlMillis = JWTUtil.JWT_TTL;
  26.         }
  27.         long expMillis = nowMillis + ttlMillis;
  28.         Date expDate = new Date(expMillis);
  29.         return Jwts.builder()
  30.                 .setId(uuid)
  31.                 .setSubject(subject)
  32.                 .setIssuer("sg")
  33.                 .setIssuedAt(now)
  34.                 .signWith(signatureAlgorithm, secretKey)
  35.                 .setExpiration(expDate);
  36.     }
  37.     public static SecretKey generalKey() {
  38.         byte[] encodeKey = Base64.getDecoder().decode(JWTUtil.JWT_KEY);
  39.         return new SecretKeySpec(encodeKey, 0, encodeKey.length, "HmacSHA256");
  40.     }
  41.     /**
  42.      * 校验JWT
  43.      */
  44.     public static Claims parseJWT(String jwt) throws Exception {
  45.         SecretKey secretKey = generalKey();
  46.         return Jwts.parserBuilder()
  47.                 .setSigningKey(secretKey)
  48.                 .build()
  49.                 .parseClaimsJws(jwt)
  50.                 .getBody();
  51.     }
  52. }
复制代码
3.3、自界说拦截器

  1. public class JWTIntercepter implements HandlerInterceptor {
  2.     public static final Logger LOGGER = LoggerFactory.getLogger(JWTIntercepter.class);
  3.     /**
  4.      * 添加用户身份认证
  5.      * @param request
  6.      * @param response
  7.      * @param handler
  8.      * @return
  9.      * @throws Exception
  10.      */
  11.     @Override
  12.     public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
  13.         String jwttoken = HttpRequestUtil.getCookieValue(request, "jwt_token");
  14.         if (jwttoken == null || jwttoken.isEmpty()) {
  15.             return false;
  16.         }
  17.         try {
  18.             Claims claims = JWTUtil.parseJWT(jwttoken);
  19.         } catch (JwtException e) {
  20.             LOGGER.info("JWT解析异常:" + e.getMessage());
  21.             return false;
  22.         }
  23.         response.sendError(ResponseEnum.USER_UNAUTHORIZED.getCode(),
  24.                 ResponseEnum.USER_UNAUTHORIZED.getMessage());
  25.         return false;
  26.     }
  27. }
复制代码
3.4、设置拦截器到拦截器链中

  1. @Configuration
  2. public class WebMVCConfig implements WebMvcConfigurer {
  3.     @Override
  4.     public void addInterceptors(InterceptorRegistry registry) {
  5.         JWTIntercepter jwtIntercepter = new JWTIntercepter();
  6.         registry.addInterceptor(jwtIntercepter)
  7.                 .addPathPatterns("/**")
  8.                 //注意:登陆和注册请求放行
  9.                 .excludePathPatterns("/user/login", "/user/register");
  10.     }
  11. }
复制代码
至此,jwt的设置已全部完成~~~ 
各人有任何问题,欢迎在评论区留言,看到会第一时间答复,如


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

忿忿的泥巴坨

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表