无法在Google API中刷新令牌

时间:2016-05-23 15:12:27

标签: php google-api google-api-php-client

目标

我需要在用户退出后从Google Analytics中获取数据。基本上他们会访问我的网站,授权我的应用访问他们的GA数据,午夜我会获取数据并在我的服务中处理它。

我目前的流量

在阅读了很多任何帖子和问题之后,我的出现是什么:
前端部分看起来有点像:

<script src="https://apis.google.com/js/client:platform.js?onload=start" async defer></script>
<script>
    function start() {
        gapi.load('auth2', function() {
            auth2 = gapi.auth2.init({
                client_id: '{{CLIENT_ID}}.apps.googleusercontent.com',
                scope: 'https://www.googleapis.com/auth/analytics',
                access_type: 'offline'
            });
        });
    }
    $('#signinButton').click(function() {
        auth2.grantOfflineAccess({
            'redirect_uri': 'postmessage'
        }).then(signInCallback);
    });

    function signInCallback(authResult) {
        window.console.log('signInCallback: This code must be exchanged by the server, it grants access to request a refresh token: ',authResult, arguments);
        if (authResult['code']) {
            // Hide the sign-in button now that the user is authorized, for example:
            $('#signinButton').attr('style', 'display: none').after('<p>The auth code is: ' + authResult['code'] + '</p>');

            $.get('http://mysite.dev/oauth_callback.php?code=' + authResult['code'])
                .fail(function(err){console.error(err)})
                .done(function(data) {
                    var message;
                    if (typeof data.error == 'undefined') {
                        message = '<div style="border: green solid 1px;">Finished the request and got ' + data + '</div>';
                    } else {
                        message = '<div style="border: red solid 1px;">' + data.message + '</div>';
                    }
                    $('#signinButton').after(message);
                });
        } else {
            // There was an error.
        }
    }
</script>

我的oauth_callback.php检查谷歌的回复并将其存储在数据库中(请忽略$ .get vs $ post位)。

从我的测试中我看到auth_code以及refresh_token和其他部分都正确存储在我的数据库中。

现在,我手动触发我的午夜脚本,看起来有点像这样:

public function get_client() {
    // Create and configure a new client object.
    $client         = new \Google_Client();
    $path_to_config = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'my-client-secret.apps.googleusercontent.com.json';
    $scopes = array(
        'https://www.googleapis.com/auth/analytics'
    );

    $client->setAuthConfigFile($path_to_config);
    $client->setApplicationName("My app");
    $client->setAccessType('offline');
    return $client;
}
public function fetch_visits() {
    foreach ($this->_accounts as $account_id => $auth_json_string) {

        $client = $this->get_client();
        $ga_code_array  = json_decode($auth_json_string, true);

        $ga_code_string = $auth_json_string;

        $client->setAccessToken($auth_json_string);
        var_dump($client);
        if ($client->isAccessTokenExpired()) {
            $client->setAccessType('offline');
            var_dump('Not authed because the access token expired. Requesting another one');
            $client->refreshToken($auth_json_string);;
            $is_authed_now = $client->isAccessTokenExpired();
            var_dump($is_authed_now);
        }
        die('sadasdsdsa');
    }
}

错误

使用此代码我得到臭名昭着: Google_Auth_Exception: Error refreshing the OAuth2 token, message: '{ "error" : "invalid_grant"" 错误,我追溯到OAuth库,基本上谷歌返回一个http代码400(而不是200)告诉我$ auth_json_string不正确,但这是谷歌在用户授权我的应用程序后给我的字符串,所以我真的不知道问题出在哪里。

请记住,这是一个服务器到服务器的应用程序,用户在我的服务运行时不会登录,这就是我存储auth json对象的原因。

你能看出我做错了吗?

1 个答案:

答案 0 :(得分:0)

对于PHP,我设置了以下内容

$客户端 - &GT; setAccessType( “refresh_token”);

这解决了我的问题。我正在使用gmail,但应该适用于其他Google服务。请记住在创建第一个access_token请求时保存refresh_token,否则您将遇到更多问题。

所以我现在有一个名为getClient()的函数

function getClient(){
    $googleUser = $this->getUserDetails();
    $client = new Google_Client();
    $client->setAuthConfigFile('client_secret.json');

    $client->setApplicationName("YOUR_APP_NAME");

    $data = $googleUser->attributes;



    $client->setAccessToken(json_encode($data));

    if($client->isAccessTokenExpired()){


        $client->addScope(Google_Service_Gmail::MAIL_GOOGLE_COM);

        $client->setAccessType("refresh_token");

        $client->refreshToken($data['refresh_token']);



        $access_token = $client->getAccessToken();


        $data1 = json_decode($access_token);


        $googleUser->access_token = $data1->access_token;
        $googleUser->token_type = $data1->token_type;
        $googleUser->expires_in = $data1->expires_in;
        $googleUser->created_date = date('Y-m-d h:i:s',$data1->created);
        $googleUser->created = $data1->created;

        $googleUser->save();


        $client->setAccessToken($access_token);

    }

    return $client;
}