JWT,全称JSON Web Token(JSON Web令牌),是一个开放标准 (rfc7519)。它定义了一种紧凑的、自包含的方式,以JSON对象的形式安全地在各方之间传输信息。这种信息可以被验证和信任,因为它是通过数字签名实现的。
JWT可以使用HMAC算法或使用RSA的公钥/私钥对进行签名,防止被篡改。JWT基于json,非常方便解析,可以在令牌中自定义丰富的内容,易扩展。通过非对称加密算法及数字签名技术,JWT防止篡改,安
全性高。
//生成JWT@Testpublic void testGenJwt(){Map<String,Object> claims = new HashMap<>();claims.put("id", 1);claims.put("name", "tom");String jwt = Jwts.builder().signWith(SignatureAlgorithm.HS256, "monian") //签名算法.setClaims(claims) //自定义内容(载荷).setExpiration(new Date(System.currentTimeMillis() + 3600 * 1000)) //设置有效期为1h.compact();System.out.println(jwt);}//解析令牌@Testpublic void testParseJwt(){Claims claims = Jwts.parser().setSigningKey("monian").parseClaimsJws("eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoidG9tIiwiaWQiOjEsImV4cCI6MTcwMTUxMTAwMH0.3ejLF6AimqpzbmTmN6WPcJvxoXAFPT9c5oNbk-0U5o4").getBody();System.out.println(claims);}
}
控制台:
eyJhbGciOiJIUzI1NiJ9.eyJuYW1lIjoidG9tIiwiaWQiOjEsImV4cCI6MTcwMTY2Mzc0NX0.HGgjyiW398CeKGosnOXGxd68KF3nJ_R8LYRrkG8-Ih8
在JWT官网解析可得:
通过测试类解析令牌可得:
Demo测试:通过JWT令牌判断用户是否登录,否则不能访问相关的数据:
@Slf4j
@WebFilter(urlPatterns = "/*")
public class LoginCheckFilter implements Filter {@Overridepublic void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {HttpServletRequest req = (HttpServletRequest) request;HttpServletResponse resp = (HttpServletResponse) response;//1.获取请求urlString url = req.getRequestURL().toString();log.info("请求的url:{}", url);//2.判断请求url是否包含login,如果包含说明是登陆操作,放行if (url.contains("login")) {log.info("登陆操作,放行...");chain.doFilter(request, response);return;}//3.获取请求头中的令牌(token)String jwt = req.getHeader("token");//4.判断令牌是否存在,如果不存在,返回错误结果(未登录)if (!StringUtils.hasLength(jwt)) {log.info("请求头token为空,返回未登录的信息");Result error = Result.error("NOT_LOGIN");//手动转化 对象——json ----> 阿里巴巴fast.JSONString notLogin = JSONObject.toJSONString(error);resp.getWriter().write(notLogin);return;}//5.解析token,如果解析失败,返回错误结果(未登录)try {JwtUtils.parseJWT(jwt);} catch (Exception e) {e.printStackTrace();log.info("解析令牌失败,返回未登录错误信息");Result error = Result.error("NOT_LOGIN");//手动转化 对象-- json --------> 阿里巴巴fastJSONString notLogin = JSONObject.toJSONString(error);resp.getWriter().write(notLogin);return;}//6.放行log.info("令牌合法,放行");chain.doFilter(request, response);}
}
详细解析:
-
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException
:这是doFilter
方法的定义,它接收三个参数:ServletRequest
对象、ServletResponse
对象和FilterChain
对象。这个方法在过滤器被调用时执行,用于处理请求和响应。 -
HttpServletRequest req = (HttpServletRequest) request;
:将传入的ServletRequest
对象强制转换为HttpServletRequest
对象,以便使用HTTP特定的方法。 -
HttpServletResponse resp = (HttpServletResponse) response;
:将传入的ServletResponse
对象强制转换为HttpServletResponse
对象,以便使用HTTP特定的方法。 -
String url = req.getRequestURL().toString();
:获取请求的URL,并将其转换为字符串。 -
String url = req.getRequestURL().toString();
:获取请求的URL,并将其转换为字符串。 -
if (url.contains("login")) {
:检查URL是否包含"login"字符串。如果包含,说明这是一个登录操作。 -
String jwt = req.getHeader("token");
:从请求头中获取名为"token"的值,并将其存储在变量jwt
中。 -
if (!StringUtils.hasLength(jwt)) {
:检查jwt
变量是否为空或长度为0。如果为空或长度为0,说明没有提供令牌。 -
String notLogin = JSONObject.toJSONString(error);
:将error
对象转换为JSON字符串。 -
JwtUtils.parseJWT(jwt);
:尝试解析提供的令牌。如果解析失败,将抛出异常。 -
String notLogin = JSONObject.toJSONString(error);
:将error
对象转换为JSON字符串。 -
resp.getWriter().write(notLogin);
:将未登录的错误信息写入响应的输出流。