OAuth2 微服务之间的认证
当我们做购物车时, 出现一个需求, 用户 -> 网关 -> 页面渲染服务 -> 订单查询服务
网关给页面渲染服务时带着令牌 (由网关直接写入 request 的 header)
页面渲染服务需要调用订单查询服务里的查询购物车, 通过 feign 的形式去调用, 但是由于订单查询受 OAuth2 保护, feign 无法直接传递令牌, 令牌到页面渲染后无法传递给订单查询
此时可以用 feign 的拦截器, 拦截器应该定义在公共模块中, 因为很多微服务都会使用这个拦截器
1. 引入openfeign依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
2. 主程序添加 @EnableFeignClients
package com.tx.tcm.user;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@EnableFeignClients
@EnableDiscoveryClient
@SpringBootApplication
public class ServiceUserApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceUserApplication.class, args);
}
}
3. yml配置文件添加如下配置;feign 启用 hystrix降级和ribbon 负载均衡和重试
ribbon:
#与服务器连接超时的时间
ConnectTimeout: 200000
#从服务器获取数据的超时时间.
ReadTimeout: 200000
#重试负载均衡其他的实例最大重试次数,不包括首次调用
MaxAutoRetriesNextServer: 1
#同一台实例最大重试次数,不包括首次调用
MaxAutoRetries: 1
#是否所有操作都重试;默认只对GET请求重试, 当设置为true时, 对POST等所有类型请求都重试
OkToRetryOnAllOperations: true
# feign 默认没有启用 hystrix,添加配置,启用 hystrix
feign:
hystrix:
enabled: true
hystrix:
command:
fallbackcmd:
execution:
isolation:
thread:
timeoutInMilliseconds: 100000 #超时时间,熔断
4. 配置传递
在配置文件ResourceServerConfig
新增feign拦截器,传递令牌
/**
* token令牌传递
*/
@Bean
public RequestInterceptor requestInterceptor(){
return new RequestInterceptor() {
@Override
public void apply(RequestTemplate requestTemplate) {
ServletRequestAttributes attributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
HttpServletRequest request = attributes.getRequest();
//添加token
requestTemplate.header(HttpHeaders.AUTHORIZATION, request.getHeader(HttpHeaders.AUTHORIZATION));
}
};
}
5. 远程调用log模块接口
创建接口文件LogService.java和LogServiceImpl降级类
@FeignClient(name = "service-log", fallback = LogServiceImpl.class)
- name:指定远程调用模块的服务名称
- fallback:指定降级类
LogService.java
package com.tx.tcm.user.system.service;
import com.tx.tcm.user.system.service.impl.LogServiceImpl;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
@FeignClient(name = "service-log", fallback = LogServiceImpl.class)
public interface LogService {
@GetMapping(value = "ping", produces = "application/json;charset=utf-8")
public String test();
}
LogServiceImpl.java
package com.tx.tcm.user.system.service.impl;
import com.tx.tcm.user.system.service.LogService;
import org.springframework.stereotype.Component;
@Component
public class LogServiceImpl implements LogService {
@Override
public String test() {
return "无法获取";
}
}