使用 Google API Java 客户端库刷新令牌

Posted

技术标签:

【中文标题】使用 Google API Java 客户端库刷新令牌【英文标题】:Refresh Token with Google API Java Client Library 【发布时间】:2013-02-03 14:31:51 【问题描述】:

我正在使用 Google API Java 客户端 http://code.google.com/p/google-api-java-client/,并且能够成功获取 android 的访问令牌。

    // Google Accounts
credential = GoogleAccountCredential.usingOAuth2(this, CalendarScopes.CALENDAR);
SharedPreferences settings = getPreferences(Context.MODE_PRIVATE);
credential.setSelectedAccountName(settings.getString(PREF_ACCOUNT_NAME, null));

由于我希望我的网络服务器进行离线 API 调用,我需要一个刷新令牌。我一直在广泛搜索,但还没有弄清楚如何去做。

理想情况下,我更喜欢使用 Google API Java 客户端而不是 WebView 来获取刷新令牌(无需输入用户名或密码)。

任何帮助将不胜感激!

【问题讨论】:

【参考方案1】:

您还可以通过创建配置为 OAuth 2.0 客户端 ID 的刷新令牌来实现此目的。

转到https://console.developers.google.com/apis/credentials

    点击“创建凭据”。 点击“OAuth 客户端 ID”。 选择“Web 应用程序”> 命名。 将 https://developers.google.com/oauthplayground 添加到“授权重定向 URI”。 点击创建。

接下来的步骤需要 ClientId 和 Secret。

那就去https://developers.google.com/oauthplayground/

    点击右上角的“AOuth 2.0 配置”。 选中“使用您自己的 OAuth 凭据”。 使用上面创建的 OAuth 2.0 凭据的客户端 ID 和密码更新“OAuth 客户端 ID”和“OAuth 客户端密码”。 在左上角的第 1 步中,选择所有必要的范围。(请注意,请求中不匹配的范围将返回 'invalid_scopes'。) 单击“授权 API”。这会将您重定向到同意页面以允许权限。 在第 2 步中,点击“兑换令牌的授权码” 您将获得一个带有刷新令牌的访问令牌。下一步我们将需要此刷新令牌。

您可以使用此访问令牌对您在范围中指定的服务进行身份验证。 访问令牌是短暂的,刷新令牌会在 24 小时后过期,除非它没有绑定到 OAuth 2.0 客户端(我们只是让我们的刷新令牌持续到它被用户撤销或由于 6 个月不活动而过期)。

您需要在访问令牌过期之前刷新它。查看以下示例以了解如何操作。

    public String getNewToken(String refreshToken, String clientId, String clientSecret) throws IOException 
            ArrayList<String> scopes = new ArrayList<>();
    
            scopes.add(CalendarScopes.CALENDAR);
    
            TokenResponse tokenResponse = new GoogleRefreshTokenRequest(new NetHttpTransport(), new JacksonFactory(),
                    refreshToken, clientId, clientSecret).setScopes(scopes).setGrantType("refresh_token").execute();
    
            return tokenResponse.getAccessToken();
    

上面示例中的clientId 和clientSecret 指的是OAuth 2.0 客户端凭据。

您可以使用这样的方式创建“GoogleCredential”

    public Credential getCredentials() throws GeneralSecurityException, IOException, FileNotFoundException 
        final NetHttpTransport HTTP_TRANSPORT = GoogleNetHttpTransport.newTrustedTransport();
        final JsonFactory JSON_FACTORY = JacksonFactory.getDefaultInstance();

        // Load client secrets.
        String CREDENTIALS_FILE_PATH = "/credentials.json"; //OAuth 2.0 clinet credentials json
        InputStream in = DriveQuickstart.class.getResourceAsStream(CREDENTIALS_FILE_PATH);
        if (in == null) 
            throw new FileNotFoundException("Resource not found: " + CREDENTIALS_FILE_PATH);
        
        GoogleClientSecrets clientSecrets = GoogleClientSecrets.load(JSON_FACTORY, new InputStreamReader(in));

        String clientId = clientSecrets.getDetails().getClientId();
        String clientSecret = clientSecrets.getDetails().getClientSecret();

        GoogleCredential credential = new GoogleCredential.Builder()
                .setTransport(HTTP_TRANSPORT)
                .setJsonFactory(JSON_FACTORY)
                .setClientSecrets(clientId, clientSecret)
                .build();

        String refreshToken = "<REFRESH-TOKEN>"; //Find a secure way to store and load refresh token
        credential.setAccessToken(getNewToken(refreshToken, clientId, clientSecret));
        credential.setRefreshToken(refreshToken);

        return credential;
    

【讨论】:

非常感谢,这完美解决了我的问题。【参考方案2】:

您需要在启动授权流程时进行以下设置:

批准提示 = 强制 访问类型 = 离线

设置这些参数后,google 将返回一个刷新令牌,而库将处理刷新。这对我有用:

new GoogleAuthorizationCodeFlow.Builder(HTTP_TRANSPORT, JSON_FACTORY, getClientCredential(),
                Arrays.asList(SCOPES)).setCredentialStore(new OAuth2CredentialStore()).setAccessType("offline")
                .setApprovalPrompt("force").build();

【讨论】:

感谢您的帮助。这是否适用于帐户选择器(即它是否适用于 GoogleAccountCredential?) 我猜,因为 GoogleAccountCredential 实现了 HttpRequestInitializer。但尝试它有助于找出答案;) 我不知道如何将它与 GoogleAccountCredential 集成,有什么提示吗? :(

以上是关于使用 Google API Java 客户端库刷新令牌的主要内容,如果未能解决你的问题,请参考以下文章

访问令牌 Google API 的刷新令牌:R 代码

Laravel Google api 客户端获取刷新令牌并上传文件

Google Api Php 客户端的刷新令牌

Google PubSub 模拟器是不是可以与 Google Cloud Pub/Sub API 客户端库一起使用?

(JAVA) Google API 分析 - 无法使用“刷新令牌”获取新的“访问令牌”

如何在 PHP 中访问 Google 电子表格 API?