spring-cloud-zuul API网关
2018-03-02 本文已影响220人
even_366
1.业务流程图
API服务接口调用认证流程图_new.jpg2. 需要依赖包pom.xml
<dependency>
##自定义异常封装
<groupId>com.exception</groupId>
<artifactId>exctption</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.41</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
3.application.yml文件,zull 路由配置采用path和URL方式
zuul:
routes:
user-center:
path: /api/user/**
url: http://127.0.0.1:9001/user #用户中心服务
log-service:
path: /api/logs/**
url: http://127.0.0.1:9092/log #日志服务
test-service:
path: /api/test/**
url: http://127.0.0.1:9003/test #测试服务
这样可以将/api/user/**映射到http://127.0.0.1:9001/user。
需要注意这种方式路由不会被HystrixCommand执行,同时不能使用Ribbon来负载多个url。
3.编写自定义Access过滤器
- 1.校验header里面是否有token
- 2.校验token是否合法
- 3.利用token获取redis缓存里面用户对应的服务授权、用户信息。存储:token作为key,authService集合方式存储[user,log,test]表示该用户拥有这3个服务调用权限。
public class AccessFilter extends ZuulFilter {
@Autowired
private TokenService tokenService;
private Logger logger = LoggerFactory.getLogger(getClass());
private final static String token="token";
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx=RequestContext.getCurrentContext();
HttpServletRequest request=ctx.getRequest();
String url=request.getRequestURI().toString();
List l=new ArrayList();
l.add("logs");
logger.info("send {} request to {}",request.getMethod(),url);
Object token=request.getHeader(AccessFilter.token);
//判断token不能为空
if(StringUtils.isEmpty(token)){
this.returnMsg(ctx,"token is empyt");
}
try {
//String v=tokenService.checkToken(token.toString());
// if(StringUtils.isEmpty(v)){
// this.returnMsg(ctx,"token is inexistence");
// }
String service=ConvertCollect.stringToStringArr(url,"/")[3];
if(!this.chooseRout(l,service)){
this.returnMsg(ctx,"no authorization "+service);
}
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
//返回没权限消息
private void returnMsg(RequestContext ctx,String msg){
ctx.getResponse().setContentType("application/json; charset=utf-8");
ctx.setSendZuulResponse(false); //令zuul过滤该请求,不对其进行路由
Result result= ResultUtil.error(401,msg);
ctx.setResponseBody(JSON.toJSONString(result));
}
/**
* 根据url验证是否有权限
* @param list
* @param service
* @return
*/
private boolean chooseRout(List<String> list, String service){
switch (service){
case ServiceName.user:
return isAuth(list,service);
case ServiceName.test:
return isAuth(list,service);
case ServiceName.logs:
return isAuth(list,service);
}
return false;
}
/**
* 判断token是否有service权限
* @param list
* @param userAuthService 用户拥有服务权限
* @return
*/
private boolean isAuth(List<String> list, String userAuthService){
return list.contains(userAuthService);
}