各个微服务的访问需要网关统一管理进行跳转,而在访问网关时,我们可以进行增强功能,通过过虑器实现请求过虑,身份校验
等。
/*** 身份校验过滤器*/
@Component
public class LoginFilter extends ZuulFilter {@AutowiredAuthService authService;/*** 过滤器类型 4种* pre:请求在被路由之前* 执行routing:在路由请求时调用* post:在routing和errror过滤器之后调用* error:处理请求时发生错误调用* @return*/@Overridepublic String filterType() {//return null 会导致 FilterProcessor - null异常return "pre";}/*** 过滤器序号* 越小越优先被执行* @return*/@Overridepublic int filterOrder() {return 0;}//是否执行过滤器@Overridepublic boolean shouldFilter() {//返回true表示执行此过滤器return true;}//过滤器得内容//过虑所有请求,判断头部信息是否有Authorization,如果没有则拒绝访问,否则转发到微服务。@Overridepublic Object run() throws ZuulException {RequestContext requestContext = RequestContext.getCurrentContext();//得到requestHttpServletRequest request = requestContext.getRequest();HttpServletResponse response = requestContext.getResponse();//cookieString tokenFormCookie = authService.getTokenFormCookie();if(StringUtils.isEmpty(tokenFormCookie)){access_denied();return null;}//hearString tokenFormHeader = authService.getTokenFormHeader(request);if(StringUtils.isEmpty(tokenFormHeader)){access_denied();return null;}//redislong expireFormRedis = authService.getExpireFormRedis(tokenFormCookie);if(expireFormRedis<0){access_denied();return null;}return null;}//拒绝访问private void access_denied(){RequestContext requestContext = RequestContext.getCurrentContext();//得到requestHttpServletRequest 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 {@AutowiredStringRedisTemplate 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返回未登录授权异常