上篇文章 Spring Cloud中如何保证各个微服务之间调用的安全性 咱们介绍了各个微服务之间调用认证的方式以及原理git
今天咱们继续接着上篇文章来聊一聊如何可以在调用方实现token的自动设置以及刷新github
咱们的认证token是放在请求头中的,相对于把token放在请求参数中更为友好,对业务接口无侵入性spring
可是这种方式若是须要本身设置token就麻烦了,若是是参数的形式,那么在调用的时候就把获取的token当作参数传就能够了缓存
House getHouseInfo(Long id, String token);
复制代码
传参的方式很差的就是每一个接口须要增长一个参数的定义安全
/**
* 获取房产信息
* @param houseId 房产编号
* @return
*/
@GetMapping("/{houseId}/{token}")
public ResponseData hosueInfo(@PathVariable("houseId")Long houseId,@PathVariable("token")String token) {
return ResponseData.ok(houseService.getHouseInfo(houseId));
}
复制代码
或者下面这种方式bash
/**
* 获取房产信息
* @param houseId 房产编号
* @return
*/
@GetMapping("/")
public ResponseData hosueInfo(Long houseId,String token) {
return ResponseData.ok(houseService.getHouseInfo(houseId));
}
复制代码
若是是PathVariable这种方式,参数是必传的,否则没法进入接口内,若是是RequestParam这种方式,方法中不定义token参数,我估计也是能够的,至少不会报错,反正咱们是统一的去判断有无权限微信
因此说咱们的token放在请求头中,是很是友好的并发
在调用接口的时候怎么往请求头中添加token呢?app
每次调用的地方都去添加token是否是太烦了?ide
其实在Zuul中咱们能够用过滤器来统一添加token,这个时候能够使用置前的过滤器pre
**
* 调用服务前添加认证请求头过滤器
*
* @author yinjihuan
* @create 2017-11-07 16:06
**/
public class AuthHeaderFilter extends ZuulFilter {
public AuthHeaderFilter() {
super();
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 0;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
ctx.addZuulRequestHeader("Authorization", TokenScheduledTask.token);
return null;
}
}
复制代码
这样在每一个请求转发到具体的微服务以前,咱们给它添加了token信息,这个token信息是咱们从TokenScheduledTask获取的
/**
* 定时刷新token
*
* @author yinjihuan
* @create 2017-11-09 15:39
**/
@Component
public class TokenScheduledTask {
private static Logger logger = LoggerFactory.getLogger(TokenScheduledTask.class);
public final static long ONE_Minute = 60 * 1000 * 60 * 20;
public static String token = "";
@Autowired
private AuthService authService;
/**
* 刷新Token
*/
@Scheduled(fixedDelay = ONE_Minute)
public void reloadApiToken() {
token = authService.getToken();
while (StringUtils.isBlank(token)) {
try {
Thread.sleep(1000);
token = authService.getToken();
} catch (InterruptedException e) {
logger.error("", e);
}
}
}
}
复制代码
原来是一个定时任务,经过调用认证的方法来获取认证好的token
##为何要作成定时的呢
若是按照通常的作法那就是请求以后都去获取一次token, 这种方式是最很差的,性能太差
稍微好点那就是在获取的地方加上缓存,貌似不错,可是有个问题是在并发的时候会存在N个请求去获取token,这边须要控制下
定时的就不存在上面的问题了,可是必定要确保定时任务的正常
我这边一个token的失效时间为24小时,因此我这边刷新的间隔是20小时,也就是说在token还没过时以前,我会自动刷新成最新的,这样就不会出现token过时的问题了
while循环是为了确保token可以正确的刷新成功
同时这个任务是在项目启动以后立马去刷新token的,这样就能确保刚过来的请求不会受到影响
具体代码能够参考个人github:
更多技术分享请关注微信公众号:猿天地