• Spring Boot


    /**
     * 自定义拦截器类
     */
    public class V8Interceptor implements HandlerInterceptor {
        @Autowired
        private Environment env; //自动注入环境变量获取配置
        @Autowired
        private StringRedisTemplate redisTmp;
    
        // token规则为 user-reids-token:userId : UUID
        private static String USER_REDIS_TOKEN = "api-token";
    
    
        /**
         * 判断用户是否登录
         *  若用户 username 不存在,则为未登录
         *  若用户 username 存在,则判断 usertoken 是否存在
         *      若存在,则用户状态为已登录
         *      若不存在,则用户状态为登录超时
         * @param request
         * @param response
         * @param handler
         * @return
         * @throws Exception
         *
         */
    
    
        public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
            // 如果是 嗅探请求,则直接放行
            String methodname = request.getMethod();
    
            if("OPTIONS".equals(methodname)){
                return true;
            }
     
            //例如:/api/wx/getmsg
            String requrl = request.getRequestURI();
     
            if (
                    (requrl.indexOf("/api/wx/")>=0) 
            ){
                //针对移动端接口的拦截处理
                String local_wxapitoken = env.getProperty("wxapitoken");
                String req_wxapitoken = request.getHeader("wxapitoken");
                if (!local_wxapitoken.equals(req_wxapitoken)){
                    //再判断是否提供了username和usertoken
                    String username = request.getHeader("username");
                    String userOldToken = request.getHeader("usertoken");
                    String v8_acname = env.getProperty("acname");
                    String errormsg = checkUserTokenInfo(username,userOldToken,acname);
    
                    if (errormsg.equals("")){
                        return true;
                    }else{
                        String info = "无效的wxapitoken或usertoken";
                        returnErrorResponse(response, JsonUtils.getErrorJson("1000", info));
                        return false;
                    }
                }else{
                    return true;
                }
            } else{ //其他情况处理
                    String username = request.getHeader("username");
                    String userOldToken = request.getHeader("usertoken");
                    String v8_acname = env.getProperty("acname");
                    String errormsg = checkUserTokenInfo(username,userOldToken,acname);
    
                    if (errormsg.equals("")){
                        return true;
                    }else{
                        returnErrorResponse(response, JsonUtils.getErrorJson("1000", errormsg));
                        return false;
                    } 
        }
    
        //判断username和usertoken是否合法
        //返回:空字符表示正确,其他表示错误原因
        public String checkUserTokenInfo(String username,String userOldToken,String acname){
            String errormsg = "";
    
            if (StrUtils.isNotBlank(username) && StrUtils.isNotBlank(userOldToken)) {
                //token的key名称格式 api-token:acname:username
                String userTokenKey = USER_REDIS_TOKEN + ":" + acname + ":" + username;
                String userToken = "";
                if (redisTmp.hasKey(userTokenKey)) {
                    userToken = redisTmp.opsForValue().get(userTokenKey).toString();
                }
    
                // 用户有token,但最新token为空,说明登录状态过期
                if (StrUtils.isBlank(userToken)) {
                    errormsg = "登录过期或未登录,请重新登录";
                    return errormsg;
                }
    
                // 两个token不一致,可能是恶意用户乱填token
                if (!userOldToken.equals(userToken)) {
                    errormsg = "无效token,请重新登录";
                    return errormsg;
                }
            } else {
                System.out.println("该用户没有登录");
                errormsg = "请登录后再操作";
                return errormsg;
            }
    
            return errormsg;
        }
    
    
        public void returnErrorResponse(HttpServletResponse response, String jsonstr) throws IOException {
            OutputStream outputStream = null ;
            try {
                response.setContentType("application/json");
                response.setCharacterEncoding("utf-8");
                outputStream = response.getOutputStream();
                outputStream.write(jsonstr.getBytes("UTF-8"));
                outputStream.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {
                if(outputStream != null){
                    outputStream.close();
                }
            }
        }
    
    
    }
    @Configuration
    public class WebMvcConfig extends WebMvcConfigurerAdapter {
    
        @Bean
        public V8Interceptor vxInterceptor(){
            return new V8Interceptor();
        }
    
    
        @Override 
        public void addCorsMappings(CorsRegistry registry) {
            //添加映射路径
            registry.addMapping("/**") 
                    .allowedOrigins("*")
                    //是否发送Cookie信息, allowedOrigins设置*,则allowCredentials不能设置true
                    .allowCredentials(false)
                    //放行哪些原始域(请求方式)
                    .allowedMethods("GET","POST", "PUT", "DELETE")
                    //放行哪些原始域(头部信息)
                    .allowedHeaders("*")
                    //暴露哪些头部信息(因为跨域访问默认不能获取全部头部信息)
                    .exposedHeaders("username", "usertoken","wxapitoken","lan_ip","net_ip");
        }
    
    
        /**
         * 设置拦截的url路径
         *
         * @param registry
         */
        @Override
        public void addInterceptors(InterceptorRegistry registry){
            //设置要拦截的接口或目录
            List listOfVerify = Arrays.asList( "/api/file/**",
                    "/api/wx/**" 
                );
    
            //设置要拦截的接口
            List listOfExc = Arrays.asList(
                    "/api/login/changeUserPwd" 
                );
    
            registry.addInterceptor(vxInterceptor())
                    .addPathPatterns(listOfVerify)
                    .excludePathPatterns(listOfExc);
            super.addInterceptors(registry);
        } 
    }
  • 相关阅读:
    VIM常用操作
    计算机之二进制基础
    交换机安全学习笔记 第六章 IPV4 ARP攻击
    交换机安全学习笔记 第八章 针对POE的攻击
    交换机安全学习笔记 第九~十章 HSRP VRRP
    CSRF-DVWA_1.9-笔记
    命令注入-笔记
    暴力破解-H3C路由器-MSR900
    暴力破解-DVWA_1.9-笔记
    DVWA、 DSVM 环境搭建简述
  • 原文地址:https://www.cnblogs.com/lpq21314/p/15188123.html
Copyright © 2020-2023  润新知