如何在 Spring Webflux WebClient 中处理令牌刷新
How to handle token refreshing in Spring Webflux WebClient
我想创建一些用于 WebClient
的身份验证服务,因此它会在需要时自动刷新令牌:
@Service
public class AuthService {
private String token;
private final WebClient webClient;
private final Map<String, String> bodyValues;
@Autowired
public AuthService(WebClient webClient) {
this.webClient = webClient;
this.bodyValues = new HashMap<>();
this.bodyValues.put("user", "myUser");
this.bodyValues.put("password", "somePassword");
}
public String getToken() {
if (this.token == null || this.isExpired(this.token) {
this.refreshToken();
}
return this.token;
}
private void refreshToken() {
this.token = webClient.post()
.uri("authEndpointPath")
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(bodyValues))
.retrieve()
.bodyToMono(String.class)
.block();
}
private boolean isExpired() {
//implementation
}
}
它在过期时正确获取令牌。有没有办法使用它 ONLY ONCE,而不将其注入其他服务?我正在考虑定义使用 authService.getToken()
方法的 Bean
:
@Configuration
public class CustomWebClientConfig {
private final AuthService authService;
@Autowired
public CustomWebClientConfig(AuthService authService) {
this.authService = authService;
}
@Bean("myCustomWebClient")
WebClient webClient() {
return WebClient.builder()
.defaultHeader("Access-Token", authService.getToken())
.build()
}
}
但显然它只会在应用程序启动时获得一次令牌。有没有办法以某种方式注入它或拦截所有 webclient 请求然后添加令牌?
您可以声明一个自定义 WebClient
和 filter 应用于每个请求。
@Configuration
public class CustomWebClientConfig {
private final AuthService authService;
@Autowired
public CustomWebClientConfig(AuthService authService) {
this.authService = authService;
}
@Bean("myCustomWebClient")
WebClient webClient() {
return WebClient.builder()
.filter(ExchangeFilterFunction.ofRequestProcessor(
(ClientRequest request) -> Mono.just(
ClientRequest.from(request)
.header("Access-Token", authService.getToken())
.build()
)
))
.build();
}
}
我想创建一些用于 WebClient
的身份验证服务,因此它会在需要时自动刷新令牌:
@Service
public class AuthService {
private String token;
private final WebClient webClient;
private final Map<String, String> bodyValues;
@Autowired
public AuthService(WebClient webClient) {
this.webClient = webClient;
this.bodyValues = new HashMap<>();
this.bodyValues.put("user", "myUser");
this.bodyValues.put("password", "somePassword");
}
public String getToken() {
if (this.token == null || this.isExpired(this.token) {
this.refreshToken();
}
return this.token;
}
private void refreshToken() {
this.token = webClient.post()
.uri("authEndpointPath")
.contentType(MediaType.APPLICATION_JSON)
.body(BodyInserters.fromValue(bodyValues))
.retrieve()
.bodyToMono(String.class)
.block();
}
private boolean isExpired() {
//implementation
}
}
它在过期时正确获取令牌。有没有办法使用它 ONLY ONCE,而不将其注入其他服务?我正在考虑定义使用 authService.getToken()
方法的 Bean
:
@Configuration
public class CustomWebClientConfig {
private final AuthService authService;
@Autowired
public CustomWebClientConfig(AuthService authService) {
this.authService = authService;
}
@Bean("myCustomWebClient")
WebClient webClient() {
return WebClient.builder()
.defaultHeader("Access-Token", authService.getToken())
.build()
}
}
但显然它只会在应用程序启动时获得一次令牌。有没有办法以某种方式注入它或拦截所有 webclient 请求然后添加令牌?
您可以声明一个自定义 WebClient
和 filter 应用于每个请求。
@Configuration
public class CustomWebClientConfig {
private final AuthService authService;
@Autowired
public CustomWebClientConfig(AuthService authService) {
this.authService = authService;
}
@Bean("myCustomWebClient")
WebClient webClient() {
return WebClient.builder()
.filter(ExchangeFilterFunction.ofRequestProcessor(
(ClientRequest request) -> Mono.just(
ClientRequest.from(request)
.header("Access-Token", authService.getToken())
.build()
)
))
.build();
}
}