springcloud 如何解决微服务之间token传递问题
作者:PaineL
这篇文章主要介绍了springcloud 如何解决微服务之间token传递问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
微服务之间token传递问题
假设现在有A服务,B服务,外部使用RESTApi请求调用A服务,在请求头上有token字段,A服务使用完后,B服务也要使用,如何才能把token也转发到B服务呢?
这里可以使用Feign的RequestInterceptor,但是直接使用一般情况下HttpServletRequest上下文对象是为空的,这里要怎么处理,请看下文。
服务A中FeginInterceptor
@Configuration public class FeginInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate requestTemplate) { Map<String,String> headers = getHeaders(getHttpServletRequest()); for(String headerName : headers.keySet()){ requestTemplate.header(headerName, getHeaders(getHttpServletRequest()).get(headerName)); } } private HttpServletRequest getHttpServletRequest() { try { return ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest(); } catch (Exception e) { e.printStackTrace(); return null; } } private Map<String, String> getHeaders(HttpServletRequest request) { Map<String, String> map = new LinkedHashMap<>(); Enumeration<String> enumeration = request.getHeaderNames(); while (enumeration.hasMoreElements()) { String key = enumeration.nextElement(); String value = request.getHeader(key); map.put(key, value); } return map; } }
服务A配置文件中添加:application.yml
hystrix: command: default: execution: isolation: strategy: SEMAPHORE
服务A添加配置文件
buildscript { ext{ springBootVersion = '1.4.5.RELEASE' //这里对应项目中的版本 } repositories { mavenCentral() } dependencies { classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") classpath "io.spring.gradle:dependency-management-plugin:0.5.6.RELEASE" } } apply plugin: 'java' apply plugin: 'org.springframework.boot' apply plugin: "io.spring.dependency-management" version = '0.0.1-SNAPSHOT' group 'com.dounine.test' sourceCompatibility = 1.8 repositories { mavenLocal() mavenCentral() } ext { springCloudVersion = 'Dalston.SR2' } dependencies { compile('org.springframework.cloud:spring-cloud-starter-config') compile('org.springframework.cloud:spring-cloud-starter-eureka') compile('org.springframework.cloud:spring-cloud-starter-feign') compile group: 'org.aspectj', name: 'aspectjweaver', version: '1.8.13' compile('org.springframework.boot:spring-boot-starter-data-redis') testCompile('org.springframework.boot:spring-boot-starter-test') } dependencyManagement { imports { mavenBom "org.springframework.cloud:spring-cloud-dependencies:${springCloudVersion}" } }
若服务B或C也想传递token,加上上述A配置即可。
微服务服务间调用传递token
微服务间的调用通常我们使用FeignClient来实现。那么如何在调用的时候传递token来保证服务间调用的安全校验呢?
没错,我们可以配置一个拦截器。该拦截器的功能就是在请求发出去前在header中添加token。
代码如下:
@Component public class FeignHeaderInterceptor implements RequestInterceptor { @Override public void apply(RequestTemplate template) { template.header(HttpHeaders.AUTHORIZATION, "token"); } }
RequestInterceptor是feign提供的接口
该接口只有一个方法:
public interface RequestInterceptor { void apply(RequestTemplate template); }
这样被调用的服务就可以在header中拿到token来做校验了。
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。