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 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 getHeaders(HttpServletRequest request) {
        Map map = new LinkedHashMap<>();
        Enumeration 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来做校验了。

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

你可能感兴趣的:(springcloud 如何解决微服务之间token传递问题)