专栏首页猿天地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

推荐阅读:

《知识点-Spring Boot 统一异常处理汇总》

《Spring Boot 1.X和2.X优雅重启实战》

《Spring Boot中快速操作Mongodb》

《面试-线程池的成长之路》

本文分享自微信公众号 - 猿天地(cxytiandi),作者:尹吉欢

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-05-30

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • Spring Cloud中Feign如何统一设置验证token

    原理是通过每个微服务请求之前都从认证服务获取认证之后的token,然后将token放入到请求头中带过去,这样被调用方通过验证token来判断是否合法请求。

    猿天地
  • Spring Cloud中Feign如何统一设置验证token

    前面我们大致的聊了下如何保证各个微服务之前调用的认证问题 Spring Cloud中如何保证各个微服务之间调用的安全性 Spring Cloud中如何保证各个微...

    猿天地
  • 一次大量删除导致 MySQL 慢查的分析

    当慢查在执行的时候,大部分的都是表现在 Sending data 的状态,我们通过 profiling 去确认下慢查的时间分布:

    猿天地
  • Flask 博客接入第三方登录

    Flask不像Django一样有各种现成的组件可以选用,Flask的各种扩展也不那么「开箱即用」。在我的博客项目中,我选用的是Authlib,它是国内的一名Py...

    岂不美哉Frost
  • Spring Cloud OAuth2 实现用户认证及单点登录

    OAuth 2 有四种授权模式,分别是授权码模式(authorization code)、简化模式(implicit)、密码模式(resource owner ...

    古时的风筝
  • Spring Boot+Redis 扛住,瞬间千次重复提交(实例)

    在实际的开发项目中,一个对外暴露的接口往往会面临,瞬间大量的重复的请求提交,如果想过滤掉重复请求造成对业务的伤害,那就需要实现幂等!

    搜云库技术团队
  • 完整部署CentOS7.2+OpenStack+kvm 云平台环境(5)--问题解决

    一、 [root@openstack-server ~]# nova list ERROR (CommandError): You must provide a...

    洗尽了浮华
  • Laravel 前后端分离项目中 Jwt-Auth + Vue 平滑刷新 Token

    Token 翻译为令牌,就是鉴别身份的凭据,类似于身份证;token 本质就是一大串字符串,最常用的场景就是接口对接的鉴权。token 通过一次登录验证,得到一...

    蓝默空间
  • 聊聊 OAuth 2.0 的 Token 续期处理

    若上,当 前端拿着正确的(未过期且未使用过)refresh_token 去调用 认证中心的刷新 端点刷新时,会 触发RefreshTokenGranter, 返...

    冷冷
  • 聊聊 OAuth 2.0 的 Token 续期处理

    若上,当 前端拿着正确的(未过期且未使用过)refresh_token 去调用 认证中心的刷新 端点刷新时,会 触发RefreshTokenGranter, 返...

    冷冷

扫码关注云+社区

领取腾讯云代金券