springcloud zuul过滤器 + redis 用户登录验证

redis 保存  key =>  token   ,values => userId

效果在最下面

TokenUtil:

@AllArgsConstructor
public class TokenUtil {

    RedisTemplate redisTemplate;
    ValueOperations valueOperations;

    private static final int TIME = 30;
    private static final String NAME = "token";

    //添加    保存为String 方便zuul过滤器 设置请求头参数
    public  String addToken(String userId){
        String token = UUID.randomUUID().toString();
        valueOperations.set(token,userId, TIME, TimeUnit.MINUTES);
        return token;
    }
    //删除
    public void deleteToken(HttpServletRequest request){
        String token = request.getHeader(NAME);
        if (token!=null){
            redisTemplate.delete(token);
        }
    }
    //解析
    public String parseToken(HttpServletRequest request){
        String token = request.getHeader(NAME);
        return token == null ? null : (String)this.valueOperations.get(token);
    }

    //刷新
    public boolean refreshToken(HttpServletRequest request){
        String token = request.getHeader(NAME);
        return token == null ? false : this.redisTemplate.expire(token, TIME, TimeUnit.MINUTES);
    }
    //解析 并 刷新
    public String parseRrefreshToken(HttpServletRequest request){
        String token = request.getHeader(NAME);
        if (null!=token && redisTemplate.expire(token, TIME, TimeUnit.MINUTES))
            return (String)this.valueOperations.get(token);
        else return null;
    }
}

zuul 过滤器:

@Component
public class TokenFilter extends ZuulFilter {

    @Autowired
    TokenUtil tokenUtil;
    @Resource
    String USER_ID_LOGIN_OVERDUE;
    static final String TARGET_URI = "ByUserId";

    // run()中 ctx.setSendZuulResponse(false); 经常导致 获取不了请求头信息,使用逻辑写这里了
    @Override
    public boolean shouldFilter() {   //是否使用该过滤器
        RequestContext ctx = RequestContext.getCurrentContext();//获取当前的 上下文对象
        HttpServletRequest request = ctx.getRequest();
        HttpServletResponse response = ctx.getResponse();

        response.setHeader("Access-Control-Allow-Origin",request.getHeader("Origin"));
        response.setHeader("Access-Control-Allow-Headers","token, content-type");
        response.setHeader("Access-Control-Allow-Credentials","true");
        response.setHeader("Access-Control-Allow-Methods","GET, HEAD, POST, PUT, DELETE, OPTIONS, PATCH");
        response.setHeader("Access-Control-Expose-Headers","X-forwared-port, X-forwarded-host");
        response.setHeader("Vary","Origin,Access-Control-Request-Method,Access-Control-Request-Headers");

        String requestURI = request.getRequestURI();   //获取请求的uri
        if (requestURI.endsWith(TARGET_URI)){    //以 ByUserId 结尾的uri进行验证
            String userId = tokenUtil.parseRrefreshToken(request);  //解析并刷新出userId
            System.out.println("token    => "+request.getHeader("token"));
            System.out.println("userId   => "+userId);
            if (userId == null ){
                return true;
            }else {
//                request.getParameterMap();    //必须加这句 不然ctx.getRequestQueryParams()失败
//                Map> requestQueryParams = ctx.getRequestQueryParams();//参数键值对map
                //如果一开始请求头里没参数 那么requestQueryParams为空
//                if (requestQueryParams==null) requestQueryParams=new HashMap<>();

                //为了提高性能 ,其他参数都放请求体了,用post请求
                Map> requestQueryParams=new HashMap<>();
                List arrayList = new ArrayList<>();
                arrayList.add(userId);      //添加 对应的values
                requestQueryParams.put("userId", arrayList); //把参数键值对放入map
                ctx.setRequestQueryParams(requestQueryParams);  //重新设置请求头所含有的参数
            }
        }
        return false;
    }


    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();//获取当前的 上下文对象
        ctx.setResponseBody(USER_ID_LOGIN_OVERDUE);
        ctx.setSendZuulResponse(false);
        return null;
    }

    @Override
    public String filterType() {
        return "pre";
    }

    @Override
    public int filterOrder() {
        return 0;
    }   //数字越小优先级越高


}

 

 

前端部分可以拦截器配合使用

比如vue 的axios:

// vue 的拦截器请求头设置token  和  zuul过滤器获取token 并验证得到userId
axios.interceptors.request.use(
  config => {
    config.headers.token = localStorage.getItem("token");
    return config;
  }
);

效果:

localhost:7010 为zuul网关    ,   user是微服务名字

请求头带了 token

springcloud zuul过滤器 + redis 用户登录验证_第1张图片

请求头没带token

springcloud zuul过滤器 + redis 用户登录验证_第2张图片

token信息不对   或者 token在redis中已经过期

springcloud zuul过滤器 + redis 用户登录验证_第3张图片

你可能感兴趣的:(springcloud,java)