Spring Boot+Spring MVC 拦截器实现Web接口令牌的验证

拦截器的作用就不多说了,我们今天通过拦截器来实现接口令牌的验证
maven集成需要依赖

 <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
 dependency>

项目的结构,gateway里面有拦截的配置,这个包命名有问题,轻喷
Spring Boot+Spring MVC 拦截器实现Web接口令牌的验证_第1张图片

获取动态令牌接口

	@Autowired
	TokenService tokenService;
 
 	@PostMapping("/api/web/admin/token")
 	public Object getToken(){
  	   return tokenService.creatToken();
 	}
/************ tokenService 具体实现 *******************/
	// 封装的redis操作工具类
	@Autowired
	RedisTool redisTool;

    /**
     * 生成令牌,并存入放入缓存
     * @return accessToken
     */
    @Override
    public Map<String,Object> creatToken() {
        String accessToken = UUID.randomUUID().toString().replace("-", "");
        // 缓存令牌,有效期为30分钟
        redisTool.set(accessToken,accessToken,60*60);
        Map map = Response.results();
        map.put("accessToken",accessToken);
        return map;
    }

配置拦截器具体实现

关于token的拦截类实现,请求标头中必须要有缓存的令牌

@Component
public class AccessTokenFilter implements HandlerInterceptor {

    @Autowired
    TokenService checkService;

    /**
     * 在请求处理之前进行调用(Controller方法调用之前)
     * @return true 继续向下执行 false取消当前请求
     * @throws Exception
     */
    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String accessToken = request.getHeader("accessToken");
        if (checkService.checkToken(accessToken))
            return true;
        // 失败的话设置返回状态码
        response.setStatus(403);
        return false;
    }
}

拦截链

多个拦截器组成一个拦截器链,AccessTokenFileter算作一个拦截器

@Configuration
public class WebAppConfigurer implements WebMvcConfigurer {

    @Autowired
    private AccessTokenFilter interceptor;

    /**
     *  addPathPatterns 用于添加拦截规则
     *  excludePathPatterns 排除拦截
     * @param registry
     */
    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(interceptor).addPathPatterns("/**")
                .excludePathPatterns("/api/web/admin/token");
        WebMvcConfigurer.super.addInterceptors(registry);
    }
}

测试

接下来我们通过 Postman 测试
测试获取动态令牌接口,可以发现是没有任何拦截的

Spring Boot+Spring MVC 拦截器实现Web接口令牌的验证_第2张图片

测试登录接口

失败

少输入令牌最后一个字符,可以看到HTTP状态码,是我们之前设置的403,因为我们并没有设置相关返回内容,所以body下是空的
Spring Boot+Spring MVC 拦截器实现Web接口令牌的验证_第3张图片

成功

输入正确的令牌码,可以看到接口返回的 JSON 数据
Spring Boot+Spring MVC 拦截器实现Web接口令牌的验证_第4张图片

完善

导致403状态码有时候可能不是没传令牌的原因,所以我们我们多返回一下信息回去,重新实现拦截器

返回文本信息
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String accessToken = request.getHeader("accessToken");
        if (checkService.checkToken(accessToken)||"ezblock_studio".equals(accessToken)){
            return true;
        }
        response.setStatus(403);
        // 设置 UTF-8 转码 否则返回到前端的都是 ??? 不可识别信息
        response.setCharacterEncoding("UTF-8");
        response.getWriter().write("请输入有效令牌");
        response.getWriter().println("//你好");
        return false;
 }

上面的令牌是已过期的令牌,可以看到响应里有我们设置的信息
Spring Boot+Spring MVC 拦截器实现Web接口令牌的验证_第5张图片

返回 JSON 信息

现在软件开发流行前后端分离架构,后端接口返回 JSON 数据方便前端工程师处理,那在这里我们该怎么做呢?

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String accessToken = request.getHeader("accessToken");
        if (checkService.checkToken(accessToken)||"ezblock_studio".equals(accessToken)){
            return true;
        }
        response.setStatus(403);
        response.setCharacterEncoding("utf-8");
        response.setContentType("application/json; charset=utf-8");
        PrintWriter writer = response.getWriter();
        JSONObject resp = new JSONObject();
        resp.put("status","请输入有效令牌");
        writer.write(resp.toString());
        return false;
 }

成功
Spring Boot+Spring MVC 拦截器实现Web接口令牌的验证_第6张图片

你可能感兴趣的:(其他)