5 身份校验 5.1 需求分析
本小节实现网关连接Redis校验令牌:
1、从cookie查询用户身份令牌是否存在,不存在则拒绝访问
2、从http header查询jwt令牌是否存在,不存在则拒绝访问
3、从Redis查询user_token令牌是否过期,过期则拒绝访问
5.2 编码代码
1、配置application.yml
配置 redis链接参数:
[AppleScript] 纯文本查看 复制代码
?
01 02 03 04 05 06 07 08 09 10 11 12 | spring : application : name : xc‐govern‐gateway redis : host : $ { REDIS_HOST : 127.0 . 0.1 } port : $ { REDIS_PORT : 6379 } timeout : 5000 #连接超时 毫秒 jedis : pool : maxActive : 3 maxIdle : 3 minIdle : 1 maxWait : ‐ 1 #连接池最大等行时间 ‐1没有限制 |
2、使用StringRedisTemplate查询key的有效期
在service包下定义AuthService类:
[AppleScript] 纯文本查看 复制代码
?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 | @Service public class AuthService { @Autowired StringRedisTemplate stringRedisTemplate; / / 查询身份令牌 public String getTokenFromCookie ( HttpServletRequest request ) { Map < String , String > cookieMap = CookieUtil.readCookie ( request , "uid" ) ; String access_token = cookieMap. get ( "uid" ) ; if ( StringUtils.isEmpty ( access_token ) ) { return null; } return access_token; } / / 从header中查询jwt令牌 public String getJwtFromHeader ( HttpServletRequest request ) { String authorization = request.getHeader ( "Authorization" ) ; if ( StringUtils.isEmpty ( authorization ) ) { / / 拒绝访问 return null; } |
[AppleScript] 纯文本查看 复制代码
?
01 02 03 04 05 06 07 08 09 10 11 12 13 | if ( !authorization.startsWith ( "Bearer " ) ) { / / 拒绝访问 return null; } return authorization; } / / 查询令牌的有效期 public long getExpire ( String access_token ) { / / token在redis中的 key String key = "user_token:" + access_token; Long expire = stringRedisTemplate.getExpire ( key ) ; return expire; } } |
说明:由于令牌存储时采用String序列化策略,所以这里用 StringRedisTemplate来查询,使用RedisTemplate无 法完成查询。
3、定义LoginFilter
[AppleScript] 纯文本查看 复制代码
?
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 | @Component public class LoginFilter extends ZuulFilter { private static final Logger LOGG = LoggerFactory.getLogger ( LoginFilter. class ) ; @Autowired AuthService authService; @Override public String filterType ( ) { / / 四种类型:pre、routing、post、 error return "pre" ; } @Override public int filterOrder ( ) { return 0 ; } @Override public boolean shouldFilter ( ) { return true ; } @Override public Object run ( ) { / / 上下文对象 RequestContext requestContext = RequestContext.getCurrentContext ( ) ; / / 请求对象 HttpServletRequest request = requestContext.getRequest ( ) ; / / 查询身份令牌 String access_token = authService.getTokenFromCookie ( request ) ; if ( access_token = = null ) { / / 拒绝访问 access_denied ( ) ; } / / 从redis中校验身份令牌是否过期 long expire = authService.getExpire ( access_token ) ; if ( expire < = 0 ) { / / 拒绝访问 access_denied ( ) ; } / / 查询jwt令牌 String jwt = authService.getJwtFromHeader ( request ) ; if ( jwt = = null ) { / / 拒绝访问 access_denied ( ) ; } return null; } / / 拒绝访问 private void access_denied ( ) { / / 上下文对象 RequestContext requestContext = RequestContext.getCurrentContext ( ) ; requestContext.setSendZuulResponse ( false ) ; / / 拒绝访问 / / 设置响应内容 ResponseResult responseResult = new ResponseResult ( CommonCode.UNAUTHENTICATED ) ; String responseResultString = JSON.toJSONString ( responseResult ) ; requestContext.setResponseBody ( responseResultString ) ; / / 设置状态码 requestContext.setResponseStatusCode ( 200 ) ; HttpServletResponse response = requestContext.getResponse ( ) ; response.setContentType ( "application/json;charset=utf‐8" ) ; } } |