JWT的定义
JWT(JSON Web Token)是一种基于 JSON 的开放标准(RFC 7519)实现的令牌。它用于在各方之间以一种紧凑且自包含的方式安全地传输信息。JWT 通常用于身份验证和信息交换。
JWT的组成
Header(头部)、Payload(负载)和 Signature(签名)。
Header:头部通常由两部分组成:令牌类型(即 JWT)和使用的签名算法(如 HMAC SHA256 或 RSA)。
{ "alg": "HS256", "typ": "JWT" }
Payload:负载是实际的声明部分,它包含一组声明(claims)。声明可以是关于实体(通常是用户)和其他数据的。声明有三种类型:registered(注册声明),public(公共声明)和private(私有声明)。
{ "sub": "1234567890", "name": "John Doe", "admin": true }
Signature:签名是为了确保 JWT 在传输过程中不会被篡改。签名的生成需要编码后的头部、编码后的负载和一个密钥,然后将这些部分进行签名。
HMACSHA256( base64UrlEncode(header) + "." + base64UrlEncode(payload), secret)
引入依赖
<dependency> <groupId>io.jsonwebtoken</groupId> <artifactId>jjwt</artifactId> <version>0.9.1</version> </dependency>
创建JwtUtils工具类
public class JwtUtils { private static String signKey = "Galvin"; //秘钥 private static Long expire = 43200000L; //时间 /** * 生成JWT令牌 * @param claims JWT第二部分负载 payload 中存储的内容 * @return */ public static String generateJwt(Map<String, Object> claims){ String jwt = Jwts.builder() .addClaims(claims) .signWith(SignatureAlgorithm.HS256, signKey) .setExpiration(new Date(System.currentTimeMillis() + expire)) .compact(); return jwt; } /** * 解析JWT令牌 * @param jwt JWT令牌 * @return JWT第二部分负载 payload 中存储的内容 */ public static Claims parseJWT(String jwt){ Claims claims = Jwts.parser() .setSigningKey(signKey) .parseClaimsJws(jwt) .getBody(); return claims; } }
signKey
: 用于签名JWT的秘钥。expire
: JWT的有效期,单位为毫秒。这里设定为43200000毫秒(12小时)。
generateJwt(Map<String, Object> claims)
: 接受一个claims
参数,类型是Map<String, Object>
,表示JWT的第二部分负载(payload)中存储的内容。Jwts.builder()
: 创建一个JWT构建器实例。addClaims(claims)
: 向JWT中添加负载(payload),即传入的claims
。signWith(SignatureAlgorithm.HS256, signKey)
: 使用HS256算法和signKey
对JWT进行签名。setExpiration(new Date(System.currentTimeMillis() + expire))
: 设置JWT的过期时间为当前时间加上expire
。compact()
: 构建并序列化JWT为字符串。
parseJWT(String jwt)
: 接受一个jwt
参数,类型是String
,表示要解析的JWT令牌。Jwts.parser()
: 创建一个JWT解析器实例。setSigningKey(signKey)
: 设置用于验证JWT签名的秘钥signKey
。parseClaimsJws(jwt)
: 解析JWT令牌并验证其签名。getBody()
: 获取解析后的JWT负载(payload),类型为Claims
。
登录时调用生成jwt
//生成jwt令牌 Map<String, Object> claims=new HashMap<>(); claims.put("id",e.getId()); claims.put("name",e.getName()); claims.put("username",e.getUsername()); String jwt= JwtUtils.generateJwt(claims);
在拦截器中解析令牌
//解析令牌 try { JwtUtils.parseJWT(jwt); } catch (Exception e){ e.printStackTrace(); log.info("解析令牌失败"); Result error=Result.error("NOT_LOGIN"); String notlogin= JSONObject.toJSONString(error); //json格式的字符串 response.getWriter().write(notlogin);//响应未登录结果 return false; }