先上图
要说的话, 都在图里
拦截器 的 优点
校验工作, 只需要 做一次
访问接口, 先经过 拦截器
接口 只 处理业务, 而不用写 校验token的 代码
springboot项目中, 配置拦截器 配置
配置 拦截器
现在 是springboot, 没有 配置文件了
现在需要 基于 Java配置
1, 拦截器, 需要交给 spring管理
package com.qfedu.fmmall.config;
import com.qfedu.fmmall.interceptor.CheckTokenInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
/**
* 在 springboot中 , 配置 拦截器
* @author beyondx
* @date Created in 2022/08/13/ 15:21
*/
@Configuration
public class InterceptorConfig implements WebMvcConfigurer {
@Autowired
private CheckTokenInterceptor checkTokenIntercepotr;
/**
* @param registry 拦截器 的 注册器
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
// 把 拦截器 注册到 Mvc, 同时 设置 拦截 和 放过的 信息
registry.addInterceptor(checkTokenIntercepotr)
.addPathPatterns("/shopcart/**")
.addPathPatterns("/orders/**")
.excludePathPatterns("/user/**");
}
}
CheckTokenInterceptor.java
package com.qfedu.fmmall.interceptor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.qfedu.fmmall.vo.ResStatus;
import com.qfedu.fmmall.vo.ResultVO;
import io.jsonwebtoken.*;
import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
/**
* @author beyondx
* @date Created in 2022/08/13/ 14:51
*/
@Component
public class CheckTokenInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
String token = request.getParameter("token");
System.out.println("---------------" + token);
if(token == null) {
ResultVO resultVO = new ResultVO(ResStatus.NO, "请先登录", null);
// 没有传 token; 提示请先登录
doResponse(response, resultVO);
} else {
try {
// 获取 解析器parser; 验证token
JwtParser parser = Jwts.parser();
parser.setSigningKey("QIANfeng6666"); // 解析token 的 SigningKey 必须和生成的token时设置的密码一致
// 如果 token正确(密码正确, 有效期内) 则正常执行, 否则抛出 异常
Jws<Claims> claimsJws = parser.parseClaimsJws(token);
return true; // 放行; 去访问接口吧
} catch (ExpiredJwtException e) {
// 登录过期
ResultVO resultVO = new ResultVO(ResStatus.NO, "登录过期, 请重新登录", null);
doResponse(response, resultVO);
} catch (UnsupportedJwtException e) {
ResultVO resultVO = new ResultVO(ResStatus.NO, "Token不合法, 请自重", null);
doResponse(response, resultVO);
} catch (Exception e) {
ResultVO resultVO = new ResultVO(ResStatus.NO, "请先登录", null);
doResponse(response, resultVO);
}
}
return false;
}
private void doResponse(HttpServletResponse response, ResultVO resultVO) throws IOException {
response.setContentType("application/json");
response.setCharacterEncoding("utf-8");
PrintWriter out = response.getWriter();
String s = new ObjectMapper().writeValueAsString(resultVO);
out.print(s);
out.flush();
out.close();
}
}