如何获得Google oauth2刷新令牌?

时间:2017-09-18 13:44:05

标签: oauth-2.0 google-api google-calendar-api google-oauth google-oauth2

以下代码使用Google oauth2机制登录用户。我们需要在用户离线时处理用户日历的更新,因此我们最终需要“刷新令牌”。 grantOfflineAccess()的结果是否返回刷新令牌(下面,我可以看到response.code包含一个可能是刷新令牌的值)?

如何获得可以使用的刷新令牌(服务器端)来创建用于离线访问用户Google日历的新访问键?

enter image description here

<script type="text/javascript">
    function handleClientLoad() {
        gapi.load('client:auth2', initClient);
    }

    function initClient() {
        gapi.client.init({
            apiKey: 'MY_API_KEY',
            clientId: 'MY_CLIENT_ID.apps.googleusercontent.com',
            discoveryDocs: ['https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest'],
            scope: 'https://www.googleapis.com/auth/calendar'
        }).then(function () {
            var GoogleAuth = gapi.auth2.getAuthInstance();
            GoogleAuth.signIn();
            GoogleAuth.grantOfflineAccess().then(function (response) {
                var refresh_token = response.code;
            });
        });
    }

</script>

<script async defer src="https://apis.google.com/js/api.js"
        onload="this.onload=function(){};handleClientLoad()"
        onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>

2 个答案:

答案 0 :(得分:1)

有一个原因是您在使用JavaScript获取刷新令牌时遇到问题。这是因为它不可能。 JavaScript是一种客户端编程语言,它必须将您的客户端ID和客户端密钥与刷新令牌一起嵌入代码中。任何在网页上执行查看源的人都可以看到这一点。我想你明白为什么这可能是一个坏主意。主要问题是gapi不会返回它,库只是没有那种能力,(不是我在原始JS中试过看看oauth服务器是否会返回它,如果我很好地问)。

您需要切换到某种服务器端语言。我听说这可以用node.js完成但是没有尝试过自己,PHP,python都是有效的选项。

答案 1 :(得分:0)

根据此post,您应在请求中包含特定的scopes。您的客户端配置应该有$client->setAccessType("offline");$client->setApprovalPrompt("force");

  

允许访问后,您将收到一个可以交换访问令牌的访问代码。返回的访问令牌是您需要保存在数据库中的令牌。稍后,如果用户需要使用日历服务,您只需使用已保存的访问令牌。

以下是示例代码:

/*
 * @$accessToken - json encoded array (access token saved to database)
*/

$client = new Google_Client();
$client->setAuthConfig("client_secret.json");
$client->addScope("https://www.googleapis.com/auth/calendar");

$_SESSION["access_token"] = json_decode($accessToken, true);

$client->setAccessToken($_SESSION['access_token']);
$service = new Google_Service_Calendar($client);

//REST OF THE PROCESS HERE