如何使用spring-boot-starter-oauth2-client实现OAuth2访问令牌刷新
解决方案
你不需要手动编写完整的令牌刷新逻辑,spring-boot-starter-oauth2-client已经内置了自动刷新令牌的全流程能力,仅需要调整现有代码使用官方提供的对应组件即可。
问题原因
你当前直接从OAuth2AuthorizedClientService加载已授权客户端的令牌,该组件仅负责令牌的持久化存储,不会自动判断令牌有效期、触发刷新流程。你需要替换为OAuth2AuthorizedClientManager组件,它内置了令牌过期校验、自动调用刷新接口、新令牌持久化的全部逻辑。
具体修改步骤
1. 配置OAuth2AuthorizedClientManager Bean
在配置类中注册支持刷新令牌的客户端管理器:
@Configuration public class OAuth2ClientConfig { @Bean public OAuth2AuthorizedClientManager authorizedClientManager( ClientRegistrationRepository clientRegistrationRepository, OAuth2AuthorizedClientService authorizedClientService) { OAuth2AuthorizedClientProvider authorizedClientProvider = OAuth2AuthorizedClientProviderBuilder.builder() .authorizationCode() .refreshToken() // 启用刷新令牌能力 .build(); DefaultOAuth2AuthorizedClientManager authorizedClientManager = new DefaultOAuth2AuthorizedClientManager( clientRegistrationRepository, authorizedClientService); authorizedClientManager.setAuthorizedClientProvider(authorizedClientProvider); return authorizedClientManager; } }
2. 调整TokenService的令牌获取逻辑
替换原有直接从OAuth2AuthorizedClientService取令牌的逻辑,改用客户端管理器获取授权客户端,自动触发刷新逻辑:
public class TokenServiceImpl implements TokenService { private final OAuth2AuthorizedClientManager authorizedClientManager; // 构造注入OAuth2AuthorizedClientManager public TokenServiceImpl(OAuth2AuthorizedClientManager authorizedClientManager) { this.authorizedClientManager = authorizedClientManager; } @Override public GoogleCredentials credentials() { final var accessToken = getAccessToken(); return getGoogleCredentials(accessToken); } private GoogleCredentials getGoogleCredentials(String accessToken) { return GoogleCredentials .newBuilder() .setAccessToken(new AccessToken(accessToken, null)) .build(); } private String getAccessToken() { final var oauthToken = (OAuth2AuthenticationToken) SecurityContextHolder.getContext().getAuthentication(); // 构造授权请求 OAuth2AuthorizeRequest authorizeRequest = OAuth2AuthorizeRequest .withClientRegistrationId(oauthToken.getAuthorizedClientRegistrationId()) .principal(oauthToken) .build(); // 管理器自动判断令牌是否过期,过期则自动刷新返回有效客户端 OAuth2AuthorizedClient authorizedClient = authorizedClientManager.authorize(authorizeRequest); return authorizedClient.getAccessToken().getTokenValue(); } }
3. 替换固定凭证提供器
你之前使用的FixedCredentialsProvider会持有初始的静态令牌,过期后不会自动更新,需要改为动态获取最新凭证的实现:
private PhotosLibraryClient getClient() { final var settings = PhotosLibrarySettings .newBuilder() .setCredentialsProvider(() -> tokenService.credentials()) .build(); return PhotosLibraryClient.initialize(settings); }
前置校验
- 确保Google OAuth授权请求携带了
access_type=offline参数,只有携带该参数时Google才会返回refresh_token,你可以在Spring配置的Google客户端授权URI后缀添加该参数,测试阶段可额外添加prompt=consent参数确保每次授权都返回refresh_token。 - 确认你的OAuth授权范围配置符合Google Photos API的要求,避免权限异常导致刷新失败。
内容的提问来源于stack exchange,提问作者Chris
相关产品推荐
相关产品推荐

