SpringBoot_拦截器实现拦截header中token

作者: 小疯子 分类: Spring Boot 发布时间: 2020-03-27 17:10

一. 前言

主要是为了在请求的时候获取到目前登陆用户的信息,这样才能和其他数据绑定啊
参考连接:https://www.jianshu.com/p/dcd6f010e048

二、实现:

基础拦截器类:

package com.xiaofeng.inventory.common.ineterceptor;

import com.alibaba.fastjson.JSON;
import com.xiaofeng.inventory.service.impl.WechatServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.Writer;
import java.util.HashMap;
import java.util.Map;

@Slf4j
public abstract class BaseInterceptor extends HandlerInterceptorAdapter {

    private static final Logger logger = LogManager.getLogger(BaseInterceptor.class);

    public void setResponse(HttpServletRequest request,
                            HttpServletResponse response, String messageKey, String message) {

        response.setContentType("application/json;charset=UTF-8");
        try (Writer writer = response.getWriter()) {
            Map<String, Object> resultMap = new HashMap<>();
            resultMap.put("code", messageKey);
            resultMap.put("message", message);
            JSON.writeJSONString(writer, resultMap);
            writer.flush();
        } catch (IOException e) {
            logger.error("respose 设置操作异常:" + e);
            e.printStackTrace();
        }
    }

    public void setResponse(HttpServletRequest request,
                            HttpServletResponse response, String messageKey) {
        setResponse(request,response,messageKey,"OK");

    }

}

具体拦截器类:

package com.xiaofeng.inventory.common.ineterceptor;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.xiaofeng.inventory.common.annotation.DisableAuth;
import com.xiaofeng.inventory.common.code.ResultCode;
import com.xiaofeng.inventory.common.helpers.ResultHelper;
import com.xiaofeng.inventory.pojo.WechatUser;
import com.xiaofeng.inventory.service.UserService;
import com.xiaofeng.inventory.utils.RedisUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.HashMap;
import java.util.Map;

@Component
public class LoginUserInterceptor extends BaseInterceptor {

    @Resource
    private RedisUtils redisUtils;

    @Resource
    private UserService userService;

    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        if(!(handler instanceof HandlerMethod)) {
            // 拦截的是方法
            return true;
        }
        // 标注此注解的方法不用拦截
        HandlerMethod method = (HandlerMethod) handler;
        DisableAuth auth = method.getMethod().getAnnotation(DisableAuth.class);
        if (auth != null) {
            return super.preHandle(request, response, handler);
        }

        // 其他方法获取token判断登陆与否
        String stoken = getAuthToken(request);
        if(StringUtils.isEmpty(stoken)) {
            setResponse(request, response, ""+ResultCode.SERVER_EXCEPTION.getCode(), "Error: stoken is null");
            return false;
        }

        // 检查token是否存在于redis中
        String ob = (String) redisUtils.get(stoken);
        if(StringUtils.isEmpty(ob)) {
            setResponse(request, response, ""+ResultCode.SERVER_EXCEPTION.getCode(), "Error: stoken is invalid");
            return false;
        }

        Map map = JSON.parseObject(ob, Map.class);
        boolean hasUser = false;
        for( Object obj : map.keySet()) {
            if("openId".equals(obj)) {
                request.setAttribute("openId", map.get(obj));
                WechatUser user = userService.getByOpenid((String) map.get(obj));
                if(!ObjectUtils.isEmpty(user)) {
                    hasUser = true;
                    request.setAttribute("userId", map.get(obj));
                }
            }
            if("sessionKey".equals(obj)) {
                request.setAttribute("sessionKey", map.get(obj));
            }
        }

        return hasUser;
    }

    /**
     * 获取http请求头部或者参数中的stoken值
     * @param request
     * @return
     */
    private String getAuthToken(HttpServletRequest request) {
        String token = request.getHeader("stoken");

        if(token == null) {
            token = request.getParameter("stoken");
        }
        return token;

    }
}

不用进行拦截的方法使用的注解:

package com.xiaofeng.inventory.common.annotation;

import java.lang.annotation.*;

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@Documented
@Inherited
public @interface DisableAuth {
}

在对应方法上:

@DisableAuth
    @RequestMapping("/login")
    public Result<Map<String, Object>> doLogin(@RequestBody WechatUserLoginRequest loginRequest) 

拦截器配置到Spring Boot环境中:

package com.xiaofeng.inventory.common.config;

import com.xiaofeng.inventory.common.ineterceptor.LoginUserInterceptor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import javax.annotation.Resource;
import java.util.List;

@Configuration
public class CustomConfig implements WebMvcConfigurer {

    @Resource
    private LoginUserInterceptor interceptor;

    public CustomConfig() {
        super();
    }

    @Override
    public void addInterceptors(InterceptorRegistry registry) {
        registry.addInterceptor(interceptor).excludePathPatterns("/login");
    }
}
0