Web客户端-在未经授权的情况下刷新API密钥



我正在寻找如何正确实现令牌刷新机制的解决方案。从外部API获得401或403 http状态代码后,应该更改令牌。我想调用登录端点来获取有效的令牌,将令牌保存到数据库中,然后使用新令牌重试。

目前,我对反应器和流有问题。以下是包含核心功能的两种方法。

寄存器方法(外部调用(

public Mono<Void> register(UserConfiguration configuration) {
return externalClient.post()
.uri("http://example.com")
.body(Mono.just(new SomeRequest()), SomeRequest.class)
.header(AUTHORIZATION_TOKEN_HEADER, token)
.exchangeToMono(clientResponse -> handleResponse(clientResponse, Void.class, configuration))
.retryWhen(Retry.max(5)
.doBeforeRetry(retrySignal -> log.info("Unauthorized request"))
.filter(UnauthorizedException.class::isInstance))
.then();
}

句柄响应方法

private <R> Mono<R> handleResponse(ClientResponse clientResponse, Class<R> clazz, Configuration configuration, ) {
if (clientResponse.statusCode().equals(HttpStatus.OK)) {
return clientResponse.bodyToMono(clazz);
} else if (clientResponse.statusCode().equals(HttpStatus.FORBIDDEN) || clientResponse.statusCode().equals(HttpStatus.UNAUTHORIZED)) {
return authenticationService.refreshToken(configuration).flatMap(conf -> Mono.error(new UnauthorizedException()));
} else {
return clientResponse.createException()
.flatMap(Mono::error);
}
}

register负责调用外部API。handleResponse负责处理响应状态,当有unauthorized响应时,该方法调用authenticationService以获得新的令牌并将令牌保存到db(UserConfiguration(中。重试检测到一个异常实例,当令牌出现问题时,它会强制流重新运行。不幸的是,register方法使用了UserConfiguration的同一个实例,因此那里的值已经过时,令牌也不再有效。

什么是更好的方法?现在,我可以看到从获取UserConfiguration开始流的唯一解决方法,因此在重试时,我们将获得数据库的最新状态。它看起来很有效,但从性能角度来看并不完美。

可能已经晚了,但如果它能帮助其他人:您可以使用onErrorResume方法来筛选401和403 HTTP响应,在这种情况下,续订令牌,将其保存在数据库中,并使用新的用户配置调用register方法。

最新更新