注:Claims对象直接会将token的有效期进行判断是否过期,所以不需要再另写相关时间比对逻辑,前端的带来的时间与后台的配置文件audience的audience.expiresSecond=1800 Claims对象会直接解析
4、拦截器的实现HTTPBasicAuthorizeHandler类的实现
在typesHandlers文件夹中新建HTTPBasicAuthorizeHandler类,代码如下:
@WebFilter(filterName = "basicFilter",urlPatterns = "/*") public class HTTPBasicAuthorizeHandler implements Filter { private static Logger logger = LoggerFactory.getLogger(HTTPBasicAuthorizeHandler.class); private static final Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("/person/exsit"))); @Autowired private Audience audience; @Override public void init(FilterConfig filterConfig) throws ServletException { logger.info("filter is init"); } @Override public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException { logger.info("filter is start"); try { logger.info("audience:"+audience.getBase64Secret()); HttpServletRequest request = (HttpServletRequest) servletRequest; HttpServletResponse response = (HttpServletResponse) servletResponse; String path = request.getRequestURI().substring(request.getContextPath().length()).replaceAll("[/]+$", ""); logger.info("url:"+path); Boolean allowedPath = ALLOWED_PATHS.contains(path); if(allowedPath){ filterChain.doFilter(servletRequest,servletResponse); }else { ReturnModel returnModel = CreateTokenUtils.checkJWT((HttpServletRequest)servletRequest,audience.getBase64Secret()); if(returnModel.getCode() == 0){ filterChain.doFilter(servletRequest,servletResponse); }else { // response.setCharacterEncoding("UTF-8"); // response.setContentType("application/json; charset=utf-8"); // response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); // ReturnModel rm = new ReturnModel(); // response.getWriter().print(rm); } } } catch (Exception e) { e.printStackTrace(); } } @Override public void destroy() { logger.info("filter is destroy"); } }
此类继承Filter类,所以重写的三个方法init、doFitler、destory,重点拦截的功能在doFitler方法中:
a、前端发来请求都会到这个方法,那么显而易见,第一登陆请求肯定不能拦截,因为它不带有token值,所以剔除登录拦截这种情况:
private static final Set<String> ALLOWED_PATHS = Collections.unmodifiableSet(new HashSet<>(Arrays.asList("/person/exsit")));
这里面的我的登录接口路径是“/person/exsit”,所以在将前端请求路径分解:
String path = request.getRequestURI().substring(request.getContextPath().length()).replaceAll("[/]+$", "");
两者进行如下比对:
Boolean allowedPath = ALLOWED_PATHS.contains(path);
根据allowedPath 的值进行判断是否拦截;
b、拦截的时候调用上述工具类的checkJWT方法,判断token是否有效:
ReturnModel returnModel = CreateTokenUtils.checkJWT((HttpServletRequest)servletRequest,audience.getBase64Secret());
ReturnModel 是我定义的返回类型结构,在model文件下;
c、如果token无效,处理代码注释了:
原因前端angular实现的拦截器和后端会冲突,导致前端代码异常,后面会详细说明。
d、配置拦截器有两种方法(这里只介绍一种):
直接在拦截类上添加注释的方法,urlPatterns是你过滤的路径,还需在服务启动的地方配置