Spring Cloud中如何保证各个微服务之间调用的安全性(下篇)

上篇文章 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获取的

TokenScheduledTask是怎么获取token的呢?

/**
 * 定时刷新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:

github.com/yinjihuan/s…

更多技术分享请关注微信公众号:猿天地

image.png
相关文章
相关标签/搜索