餐饮智能互联平台技术要点——JWT拦截器
简介
实现一个拦截器(Interceptor),用于在处理HTTP请求之前对JWT(JSON Web Token)令牌进行校验。
JWT是一种用于身份验证和授权的令牌标准,通常包含用户信息和权限等信息,用于在客户端和服务器之间传递身份信息。
实现思路

代码实现
在sky-server模块中,com.sky.interceptor.JwtTokenAdminInterceptor。
/**
* 校验jwt
*
* @param request
* @param response
* @param handler
* @return
* @throws Exception
*/
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
//判断当前拦截到的是Controller的方法还是其他资源
if (!(handler instanceof HandlerMethod)) {
//当前拦截到的不是动态方法,直接放行
return true;
}
//1、从请求头中获取令牌 jwtProperties.getAdminTokenName()获取为token
String token = request.getHeader(jwtProperties.getAdminTokenName());
//2、校验令牌
try {
log.info("jwt校验:{}", token);
Claims claims = JwtUtil.parseJWT(jwtProperties.getAdminSecretKey(), token);
Long empId = Long.valueOf(claims.get(JwtClaimsConstant.EMP_ID).toString());
log.info("当前员工id:", empId);
BaseContext.setCurrentId(empId);
//3、通过,放行
return true;
} catch (Exception ex) {
//4、不通过,响应401状态码
response.setStatus(401);
return false;
}
}
在sky-common模块中,com.sky.controller.utils.JwtUtil。
/**
* Token解密
*
* @param secretKey jwt秘钥 此秘钥一定要保留好在服务端, 不能暴露出去, 否则sign就可以被伪造, 如果对接多个客户端建议改造成多个
* @param token 加密后的token
* @return
*/
public static Claims parseJWT(String secretKey, String token) {
// 得到DefaultJwtParser
Claims claims = Jwts.parser()
// 设置签名的秘钥
.setSigningKey(secretKey.getBytes(StandardCharsets.UTF_8))
// 设置需要解析的jwt
.parseClaimsJws(token).getBody();
return claims;
}
这段代码实现了一个JWT令牌的验证拦截器,用于保护某些Controller方法,确保只有携带有效令牌的请求能够访问它们。如果令牌验证成功,会将员工ID设置到当前线程的上下文中,以便后续的代码可以使用该信息。如果令牌验证失败,请求将被拒绝。这是一种常见的身份验证和授权机制,用于保护Web应用程序的安全性。
代码解读
-
JwtTokenAdminInterceptor 类是Spring框架的组件(Component),它实现了 HandlerInterceptor 接口,用于拦截请求并在请求处理前进行JWT令牌的验证。
-
preHandle 方法是拦截器的主要方法,在请求到达Controller方法之前调用。该方法接受三个参数:HttpServletRequest request 表示HTTP请求对象,HttpServletResponse response 表示HTTP响应对象,Object handler 表示处理请求的方法对象。
-
在方法开始处,通过判断 handler 是否是 HandlerMethod 的实例,来确定当前拦截的是Controller的方法还是其他资源。如果不是Controller的方法,直接放行,不进行JWT令牌的校验。如果 handler 是 HandlerMethod 的实例,说明拦截到的是Controller的方法,接下来进行JWT令牌的校验。
-
从HTTP请求头中获取JWT令牌。
-
尝试解析JWT令牌,如果解析成功,会得到JWT中的声明(Claims),并从中提取出员工ID。
-
如果JWT解析成功,将员工ID设置到当前线程的上下文中,以便后续的请求可以访问该员工ID。这通常是为了在请求处理过程中获取当前用户的身份信息。
-
最后,如果JWT令牌验证通过,preHandle 方法返回 true,允许请求继续执行Controller方法;如果JWT令牌验证失败,将HTTP响应状态码设置为401(未授权),并返回 false,拒绝请求继续执行。
HandlerMethod详解
简介
在Spring框架中,HandlerMethod 表示一个处理请求的具体Controller方法。它是Spring MVC中的一个类,用于描述和包装处理HTTP请求的Controller方法的相关信息,包括Controller的类实例、方法名、方法参数等。
它通常在请求被拦截器、拦截器链或处理器适配器中使用,用于确定应该调用哪个Controller方法来处理请求。
示例
例如,在上述拦截器中,可以使用 instanceof 来检查 handler 是否是 HandlerMethod 的实例,以确定当前拦截的是Controller的方法:
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
if (handler instanceof HandlerMethod) {
HandlerMethod handlerMethod = (HandlerMethod) handler;
// 确定拦截到的是Controller的方法
String methodName = handlerMethod.getMethod().getName();
String className = handlerMethod.getBeanType().getName();
System.out.println("拦截到的Controller方法:" + className + "." + methodName);
}
// 继续处理或放行请求
return true;
}
在上面的代码中,我们首先检查 handler 是否是 HandlerMethod 的实例,如果是,就可以获取有关该Controller方法的信息,如方法名和类名等。
通过 HandlerMethod,Spring MVC能够更精确地调用匹配的Controller方法,以确保请求被正确处理。这在处理RESTful API请求时尤其有用,因为一个Controller类中可能有多个方法,根据请求的URL和HTTP方法的不同来决定调用哪个方法。

浙公网安备 33010602011771号