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

如何在Spring Boot中从Google OAuth获取Refresh Token?

解决Spring Boot中Google OAuth2获取Refresh Token的问题

核心结论:不能通过request.getParameter("code")获取授权码

Spring Security OAuth2登录流程中,回调请求里的code参数会被框架自动捕获,用来交换Access Token和Refresh Token,这个过程完成后code就会被移除,所以在onAuthenticationSuccess方法里无法通过request参数拿到它。

正确获取Refresh Token的步骤

1. 确保OAuth2请求携带access_type=offline参数

Google OAuth2只有在请求中包含access_type=offline时才会返回Refresh Token,同时添加prompt=consent可以强制用户重新授权,避免用户已授权过就不再返回Refresh Token的情况。

可以通过自定义OAuth2AuthorizationRequestResolver来添加这些参数:

@Bean
public OAuth2AuthorizationRequestResolver authorizationRequestResolver(ClientRegistrationRepository clientRegistrationRepository) {
    DefaultOAuth2AuthorizationRequestResolver resolver = new DefaultOAuth2AuthorizationRequestResolver(clientRegistrationRepository, "/oauth2/authorize");
    resolver.setAuthorizationRequestCustomizer(customizer -> customizer
            .additionalParameters(params -> params.put("access_type", "offline"))
            .additionalParameters(params -> params.put("prompt", "consent")));
    return resolver;
}

然后在你的oauth2Login配置中关联这个Resolver:

.oauth2Login()
    .authorizationEndpoint()
        .authorizationRequestResolver(authorizationRequestResolver())
        .baseUri("/oauth2/authorize")
        .authorizationRequestRepository(cookieAuthorizationRequestRepository())
        .and()
    // 其他原有配置...

2. 在onAuthenticationSuccess中从Authentication对象提取Refresh Token

框架完成code交换后,会把Access Token和Refresh Token封装到OAuth2AccessToken对象中,你可以从Authentication令牌里直接获取:

public void onAuthenticationSuccess(HttpServletRequest request,
                                    HttpServletResponse response,
                                    Authentication authentication)
        throws IOException, ServletException {
    if (authentication instanceof OAuth2AuthenticationToken oauth2Token) {
        OAuth2AccessToken accessToken = oauth2Token.getAccessToken();
        OAuth2RefreshToken refreshToken = accessToken.getRefreshToken();
        if (refreshToken != null) {
            String refreshTokenValue = refreshToken.getTokenValue();
            // 这里可以将refresh token存储到数据库或其他持久化介质
        }
    }
    // 后续的成功跳转逻辑...
}

额外说明

  • 你之前构建的GoogleAuthorizationCodeFlow其实不需要单独使用,Spring Security已经帮你完成了code交换token的流程,直接用框架提供的对象即可。
  • 如果是OIDC场景(你配置了oidcUserService),Refresh Token依然从OAuth2AccessToken中提取,OidcUser的getIdToken()主要存放身份相关信息。

内容的提问来源于stack exchange,提问作者nomadus

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 01:03:27