打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

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

前言

赠书活动马上就要结束啦!还没参与的小伙伴查看文章参与吧。

赠书|感谢关注猿天地的朋友们

上篇文章 Spring Cloud中如何保证各个微服务之间调用的安全性 我们介绍了各个微服务之间调用认证的方式以及原理。

今天我们继续接着上篇文章来聊一聊如何能够在调用方实现token的自动设置以及刷新。

我们的认证token是放在请求头中的,相对于把token放在请求参数中更为友好,对业务接口无侵入性。

但是这种方式如果需要自己设置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));
}

或者下面这种方式:

/**
* 获取房产信息
* @param houseId 房产编号
* @return
*/

@GetMapping('/')
public ResponseData hosueInfo(Long houseId,String token) {
   return ResponseData.ok(houseService.getHouseInfo(houseId));
}

如果是PathVariable这种方式,参数是必传的,不然无法进入接口内,如果是RequestParam这种方式,方法中不定义token参数,我估计也是可以的,至少不会报错,反正我们是统一的去判断有无权限。

所以说我们的token放在请求头中,是非常友好的一种方式。

接下来我们说说使用的问题

在调用接口的时候怎么往请求头中添加token呢?

每次调用的地方都去添加token是不是太烦了?

其实在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:

https://github.com/yinjihuan/spring-cloud

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
使用JWT和Spring Security保护REST API
ASP.Net Core 3.1 中使用JWT认证
微服务网关鉴权:gateway使用、网关限流使用、用户密码加密、JWT鉴权
SAP Spartacus UI 通过 HTTP Interceptor 给请求添加 Authorization 字段的源代码分析
.NET Web API之filter ActionFilterAttribute 过滤器使用
Avatar · TesterHome
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服