• 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);
        } 
    }
  • 相关阅读:
    xml根据属性去重。如csprj去重
    table中td的内容换行。
    基于jq的表单填充
    c#包含类文件到csprj中
    t4 根据表名数组生成实体
    js中找string中重复项最多的字符个数
    一步步配置cordova android开发环境
    .net framework卸载工具
    Sql Server查询视图和表
    DbHelper.ttinclude 更新,查询视图和表
  • 原文地址:https://www.cnblogs.com/lpq21314/p/15188123.html
Copyright © 2020-2023  润新知