登录拦截器LoginFilter正确打开方式(Token验证、将统一参数放入ServletRequest中)

最近半年公司一直搞一套抖音营销系统,基于组织架构,角色分类比较多:
0 普通, 1 组织机构创建人,2 超级管理员, 3 离职 , 4 删除 , 5 未激活

就想着用过滤器+拦截器的方式将用户信息处理好,将统一的参数保存在ServletRequest以便Controller使用,话不多说,放源码:


/**
 * 登录拦截器,如果检测到Token伪登录则踢出系统
 */
public class LoginFilter implements Filter, HandlerInterceptor {

    @Autowired
    private RecursiveService recursiveService;


    private final static ArrayList<String> urlList = new ArrayList<>();

    static {
        urlList.add("/mobile/getTiktokVideoList");
        urlList.add("/mobile/getTalentFansList");
    }

    @Override
    public void init(FilterConfig filterConfig) {

    }

    @SneakyThrows
    @Override
    public void doFilter(ServletRequest req, ServletResponse response, FilterChain chain) {
        HttpServletRequest request = (HttpServletRequest) req;
        Logger log = LoggerFactory.getLogger(StartApplicationServer.class);
        long start = System.currentTimeMillis(); // 请求进入时间
        //验证用户是否登录,如果伪登录userInfo==null
        JSONObject userJsonObject = this.validatorLogin(request, response);
        if (null == userJsonObject) {
            return;
        }
        request = new BodyRequestWrapper(request, buildRequestBody(request, userJsonObject));
        chain.doFilter(request, response);
        //api耗时输出
        log.info("API耗时: {},{}", request.getRequestURI(), System.currentTimeMillis() - start);
    }


    /**
     * Controller方法调用之后统一关闭资源
     */
    @Override
    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) {
        //关闭redis
        RedisClient.destructor();
    }

    @Override
    public void destroy() {

    }


    //获取Request的body数据
    private String getBody(ServletRequest request) {
        StringBuilder stringBuilder = new StringBuilder();
        BufferedReader bufferedReader = null;
        InputStream inputStream = null;
        try {
            inputStream = request.getInputStream();
            if (inputStream != null) {
                bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
                char[] charBuffer = new char[128];
                int bytesRead;
                while ((bytesRead = bufferedReader.read(charBuffer)) > 0) {
                    stringBuilder.append(charBuffer, 0, bytesRead);
                }
            }
        } catch (IOException ignored) {

        } finally {
            if (inputStream != null) {
                try {
                    inputStream.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            if (bufferedReader != null) {
                try {
                    bufferedReader.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
        return stringBuilder.toString();
    }


    /**
     * 填充当前登录用户的信息
     *
     * @param request
     * @param userJsonObject
     * @return
     */
    private String buildRequestBody(HttpServletRequest request, JSONObject userJsonObject) {
        String requestBody = getBody(request);
        //如果body中存在数据放入HttpServletRequest
        if (StringUtils.isNotEmpty(requestBody)) {
            //参数中放入新的参数
            JSONObject requestJsonObject = JSONObject.parseObject(requestBody);
            requestJsonObject.put("path", request.getServletPath());
            requestJsonObject.put("orgId", userJsonObject.getLongValue("OrgId"));
            requestJsonObject.put("orgKey", userJsonObject.getString("OrgKey"));
            requestJsonObject.put("userId", userJsonObject.getLongValue("UserId"));
            requestJsonObject.put("userRole", userJsonObject.getIntValue("Status"));
            JSONObject feishuJsonObj = userJsonObject.getJSONObject("Feishu");
            if (null != feishuJsonObj) {
                requestJsonObject.put("appId", feishuJsonObj.getString("AppId"));
            }
            BasePojo basePojo = ProjectConfig.getJsonValue(requestJsonObject.toJSONString(), BasePojo.class, null);
            if (!urlList.contains(basePojo.getPath())) {
                recursiveService.getUserIdsByDepts(basePojo, basePojo.getOrgId());
                requestJsonObject.put("userIdSet", basePojo.getUserIdSet());
            }
            requestBody = requestJsonObject.toJSONString();
        }
        return requestBody;
    }


    /**
     * 验证用户是否登录,已登录用户存储到Redis缓存中
     *
     * @param request
     * @param response
     * @return
     * @throws IOException
     */
    public JSONObject validatorLogin(HttpServletRequest request, ServletResponse response) throws IOException {
        response.setContentType("application/json;");
        String headerToken = request.getHeader(ProjectConfig.PARAM_HEADER_TOKEN_NAME);
        if (!StringUtils.isNotEmpty(headerToken) || !headerToken.startsWith(String.format("%s ", ProjectConfig.PARAM_HEADER_TOKEN_PREFIX))) {
            return null;
        }
        String authToken = headerToken.substring(headerToken.lastIndexOf(" ") + 1);
        String redisTokenKey = String.format("%s%s", ProjectConfig.LOGIN_USER_REDIS_KEY_PREFIX, authToken);
        String redisValue = RedisClient.getInstance().get(redisTokenKey);
        JSONObject jsonObject = null;
        if (StringUtils.isNotEmpty(redisValue)) {
            jsonObject = ProjectConfig.getJsonValue(redisValue, JSONObject.class, null);
            return jsonObject;
        }
        String requestUrl = String.format("%s%s", ProjectConfig.CLIENT_SERVER_URL, "/user?feishu=true&douyin=true");
        ClientHttpRestTemplate.ClientHttpResponse clientHttpResponse = new ClientHttpRestTemplate().sendAuthRequest(authToken, requestUrl, HttpMethod.GET, null);
        if (!clientHttpResponse.isSuccess()) {
            PrintWriter out = response.getWriter();
            out.append(clientHttpResponse.getSourceJson().toJSONString());
            return null;
        }
        //redis缓存用户信息
        RedisClient.getInstance().put(redisTokenKey, clientHttpResponse.getData().toJSONString(), 5, TimeUnit.MINUTES);
        return clientHttpResponse.getData();
    }


    /**
     * 重置HttpServletRequest InputStream
     */
    public static class BodyRequestWrapper extends HttpServletRequestWrapper {

        // 存放JSON数据主体
        private String body;

        public BodyRequestWrapper(HttpServletRequest request, String context) {
            super(request);
            body = context;
        }

        @Override
        public ServletInputStream getInputStream() throws IOException {
            final ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(body.getBytes("UTF-8"));
            ServletInputStream servletInputStream = new ServletInputStream() {
                @Override
                public int read() throws IOException {
                    return byteArrayInputStream.read();
                }

                @Override
                public boolean isFinished() {
                    return false;
                }

                @Override
                public boolean isReady() {
                    return false;
                }

                @Override
                public void setReadListener(ReadListener listener) {

                }
            };
            return servletInputStream;
        }

        @Override
        public BufferedReader getReader() throws IOException {
            return new BufferedReader(new InputStreamReader(this.getInputStream()));
        }
    }

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值