ZuulFilter的使用场景

各个微服务的访问需要网关统一管理进行跳转,而在访问网关时,我们可以进行增强功能,通过过虑器实现请求过虑,身份校验

等。

/**
 * 身份校验过滤器
 */
@Component
public class LoginFilter extends ZuulFilter {

    @Autowired
    AuthService authService;

    /**
     * 过滤器类型 4种
     *  pre:请求在被路由之前
     *  执行routing:在路由请求时调用
     *  post:在routing和errror过滤器之后调用
     *  error:处理请求时发生错误调用
     * @return
     */
    @Override
    public String filterType() {
        //return null 会导致 FilterProcessor - null异常
        return "pre";
    }

    /**
     * 过滤器序号
     * 越小越优先被执行
     * @return
     */
    @Override
    public int filterOrder() {
        return 0;
    }

    //是否执行过滤器
    @Override
    public boolean shouldFilter() {
        //返回true表示执行此过滤器
        return true;
    }

    //过滤器得内容
    //过虑所有请求,判断头部信息是否有Authorization,如果没有则拒绝访问,否则转发到微服务。
    @Override
    public Object run() throws ZuulException {
        RequestContext requestContext = RequestContext.getCurrentContext();
        //得到request
        HttpServletRequest request = requestContext.getRequest();
        HttpServletResponse response = requestContext.getResponse();
        //cookie
        String tokenFormCookie = authService.getTokenFormCookie();
        if(StringUtils.isEmpty(tokenFormCookie)){
            access_denied();
            return null;
        }
        //hear
        String tokenFormHeader = authService.getTokenFormHeader(request);
        if(StringUtils.isEmpty(tokenFormHeader)){
            access_denied();
            return null;
        }
        //redis
        long expireFormRedis = authService.getExpireFormRedis(tokenFormCookie);
        if(expireFormRedis<0){
            access_denied();
            return null;
        }
        return null;
    }




    //拒绝访问
    private void access_denied(){
        RequestContext requestContext = RequestContext.getCurrentContext();
        //得到request
        HttpServletRequest request = requestContext.getRequest();
        HttpServletResponse response = requestContext.getResponse();
        //拒绝访问
        requestContext.setSendZuulResponse(false);
        //回复响应
        requestContext.setResponseStatusCode(200);
        ResponseResult responseResult = new ResponseResult(CommonCode.UNAUTHENTICATED);
        String s = JSON.toJSONString(responseResult);
        requestContext.setResponseBody(s);
        response.setContentType("application/json;charset=utf-8");
    }

}

@service

@Service
public class AuthService {

    @Autowired
    StringRedisTemplate stringRedisTemplate;

    //从cookie中获取jwt令牌
    public String getTokenFormCookie() {
        HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
        Map<String, String> map = CookieUtil.readCookie(request, "uid");
        if(map!=null&&map.get("uid")!=null){
            return map.get("uid");
        }
        return null;
    }

    //从请求头中获取jwt令牌
    public String getTokenFormHeader(HttpServletRequest request) {
        String authorization = request.getHeader("Authorization");
        if(StringUtils.isEmpty(authorization)){
            return null;
        }
        if(!authorization.startsWith("Bearer ")){
            return null;
        }
        String jwt = authorization.substring(7);
        return jwt;
    }

    //从redis获取过期时间
    public long getExpireFormRedis(String access_token){
        String key ="user_token:" + access_token;
        Long expire = stringRedisTemplate.getExpire(key, TimeUnit.SECONDS);
        return expire;
    }
}

可以从代码中看到,我们LoginFilter继承ZuulFilter后实现4个子方法,分别是1.过滤器的类型(处理时机), 2.此过滤器的优先级 3.是否执行此过滤器 4.过滤器的内容。  

我们实现了一个在请求被路由之前的身份验证功能,在4中获取request中的

1.判断request中的cookie是否有jwt身份短令牌,没有则拒绝访问

2.判断request的Header中是否有jwt令牌,没有则拒绝访问

3.判断redis中此令牌是否过期,过期则拒绝访问

最后,都满足则路由跳转至指定微服务,不满足则response返回未登录授权异常

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值