You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 00:18:00