本文共 4832 字,大约阅读时间需要 16 分钟。
在服务器端保存session无状态不需要session,把登陆状态保存在cookie中
无状态登录的流程:
token:登陆时,jwt oath2 jwt:头信息(jwt) 载荷(用户信息,签发人 签发时间 有效时间) 签名(头信息+载荷:通过加密算法生成。作用:校验前两部分内容的合法性)
聚合工程:leyou-auth-common(jwt相关的工具类) leyou-auth-service(微服务)
因为生成jwt,解析jwt这样的行为以后在其它微服务中也会用到,因此我们会抽取成工具。我们把鉴权中心进行聚合,一个工具module,一个提供服务的module
在leyou-auth-servcice编写一个接口,对外提供登录授权服务。基本流程如下:
根据载荷还有私钥生成jwt类型的token根据公钥解析jwt类型的token,获取载荷信息(userInfo)rsaUtils(生成公钥和私钥文件,并且读取公钥和私钥文件返回公钥和私钥对象)
1.调用user-service中的queryUser接口,验证用户是否正确2.判断返回的用户信息是否为空3.生成jwt类型的token4.token信息设置到cookie中
1.获取Cookie中jwt类型的token @CookieValue("LY_TOKEN")2.jwtUtils解析jwt,获取用户信息 判断用户是否为空3.刷新jwt时间 cookie时间4.响应用户信息
在Zuul编写拦截器,对用户的token进行校验,如果发现未登录,则进行拦截。
![]()
基本逻辑:
@Component@EnableConfigurationProperties(JwtProperties.class)public class LoginFilter extends ZuulFilter { @Autowired private JwtProperties properties; @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 5; } @Override public boolean shouldFilter() { return true; } @Override public Object run() throws ZuulException { // 获取上下文 RequestContext context = RequestContext.getCurrentContext(); // 获取request HttpServletRequest request = context.getRequest(); // 获取token String token = CookieUtils.getCookieValue(request, this.properties.getCookieName()); // 校验 try { // 校验通过什么都不做,即放行 JwtUtils.getInfoFromToken(token, this.properties.getPublicKey()); } catch (Exception e) { // 校验出现异常,返回403 context.setSendZuulResponse(false); context.setResponseStatusCode(HttpStatus.FORBIDDEN.value()); } return null; }}
并不是所有的路径我们都需要拦截,例如:
另外,跟后台管理相关的接口,因为我们没有做登录和权限,因此暂时都放行,但是生产环境中要做登录校验:
所以,我们需要在拦截时,配置一个白名单,如果在名单内,则不进行拦截。
在application.yaml中添加规则:leyou: filter: allowPaths: - /api/auth - /api/search - /api/user/register - /api/user/check - /api/user/code - /api/item
然后读取这些属性:
@ConfigurationProperties(prefix = "leyou.filter")public class FilterProperties { private ListallowPaths; public List getAllowPaths() { return allowPaths; } public void setAllowPaths(List allowPaths) { this.allowPaths = allowPaths; }}
在过滤器中的shouldFilter
方法中添加判断逻辑
@Component@EnableConfigurationProperties({ JwtProperties.class, FilterProperties.class})public class LoginFilter extends ZuulFilter { @Autowired private JwtProperties jwtProp; @Autowired private FilterProperties filterProp; private static final Logger logger = LoggerFactory.getLogger(LoginFilter.class); @Override public String filterType() { return "pre"; } @Override public int filterOrder() { return 5; } @Override public boolean shouldFilter() { // 获取上下文 RequestContext ctx = RequestContext.getCurrentContext(); // 获取request HttpServletRequest req = ctx.getRequest(); // 获取路径 String requestURI = req.getRequestURI(); // 判断白名单 // 遍历允许访问的路径 for (String path : this.filterProp.getAllowPaths()) { // 然后判断是否是符合 if(requestURI.startsWith(path)){ return false; } } return true; } @Override public Object run() throws ZuulException { // 获取上下文 RequestContext ctx = RequestContext.getCurrentContext(); // 获取request HttpServletRequest request = ctx.getRequest(); // 获取token String token = CookieUtils.getCookieValue(request, jwtProp.getCookieName()); // 校验 try { // 校验通过什么都不做,即放行 JwtUtils.getInfoFromToken(token, jwtProp.getPublicKey()); } catch (Exception e) { // 校验出现异常,返回403 ctx.setSendZuulResponse(false); ctx.setResponseStatusCode(403); logger.error("非法访问,未登录,地址:{}", request.getRemoteHost(), e ); } return null; }}
转载地址:http://vxxab.baihongyu.com/