Google API Oauth php 永久访问

Posted

技术标签:

【中文标题】Google API Oauth php 永久访问【英文标题】:Google API Oauth php permanent access 【发布时间】:2012-09-13 21:29:23 【问题描述】:

我正在使用谷歌日历 API。这就是我想要的,一旦您授予应用程序权限,我就可以随时使用该应用程序,而无需每天授予访问权限。我一直听说我需要保存访问令牌或使用刷新令牌来做我想做的事情。这是事情,你是怎么做的?代码看起来如何?我尝试将令牌保存在 cookie 中,但一个小时后,访问令牌已过期。如何让用户保持登录状态?

PS:请给我代码示例和解释。

这是我的代码(使用 Cakephp):

$client = new Google_Client();

    $client->setApplicationName("Wanda3.0 Agenda");

    $cal = new Google_CalendarService($client);

    if (isset($_GET['code'])) 

        $client->authenticate($_GET['code']);


        $_SESSION['token'] = $client->getAccessToken();


        header('Location: http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']);

    

    if (isset($_SESSION['token']))  $client->setAccessToken($_SESSION['token']); 

if ($client->getAccessToken()) 
        /************* Code entry *************/


    else
        /************* Not connected to google calendar code *************/
        $authUrl = $client->createAuthUrl();

        $returnArr = array('status' => 'false', 'message' => "<a class='login' href='$authUrl'>Connect Me!</a>");

        return $returnArr;

    

【问题讨论】:

访问令牌过期 - 这就是您获得刷新令牌的原因。您应该能够使用身份验证时获得的刷新令牌获取新的访问令牌(和更新的刷新令牌)。 (不幸的是,我没有任何代码示例) (但是,只有在原始访问令牌已过期时才使用刷新令牌:***.com/a/10186904/1313164) @TerrySeidler 理论上我知道该怎么做,或者至少这是我目前所理解的:当访问令牌过期时,我想使用刷新令牌来获取新令牌,但是最大的问题是如何在实践中做到这一点。 我明白了!你可以试试这个页面上的最后一条评论,似乎对那个人有用:code.google.com/p/google-api-php-client/issues/detail?id=94 检查了您发送的内容并应用了它,等了一个小时,它仍然登录!我的最终测试是等待几天,看看它是否仍然登录。如果它仍然有效,请向@TerrySeidler 致敬!我会在几天内回答这个问题! 【参考方案1】:

好的,等了几天,Terry Seidler(下面的cmets)的建议让这一切发生了!这是我关于如何自动刷新访问令牌而无需每次使用 cookie 进行身份验证的代码。

(注意:将刷新令牌保存在数据库中更安全)

这就是魔法(使用 cookie):

$client = new Google_Client();

    $client->setApplicationName("Wanda3.0 Agenda");

    $cal = new Google_CalendarService($client);

    $client->setAccessType('offline');

    if (isset($_GET['code'])) 

        $client->authenticate($_GET['code']);

        $_SESSION['token'] = $client->getAccessToken();

        header('Location: http://'.$_SERVER['HTTP_HOST'].$_SERVER['PHP_SELF']);

    

    //Where the magic happends
    if (isset($_SESSION['token'])) 

        //Set the new access token after authentication
        $client->setAccessToken($_SESSION['token']);

        //json decode the session token and save it in a variable as object
        $sessionToken = json_decode($_SESSION['token']);

        //Save the refresh token (object->refresh_token) into a cookie called 'token' and make last for 1 month
        $this->Cookie->write('token', $sessionToken->refresh_token, false, '1 month');
    

    //Each time you need the access token, check if there is something saved in the cookie.
    //If $cookie is empty, you are requested to get a new acces and refresh token by authenticating.
    //If $cookie is not empty, you will tell the client to refresh the token for further use,
    // hence get a new acces token with the help of the refresh token without authenticating..
    $cookie = $this->Cookie->read('token');

    if(!empty($cookie))
        $client->refreshToken($this->Cookie->read('token'));
    

就是这样!如果您有任何疑问,请随时在下面发表评论,我会尽力回答。祝你好运,干杯!

【讨论】:

这会导致每次都调用 refreshToken 吗?这是一件坏事吗?【参考方案2】:

您应该将其保存在数据库中并使用它,而不是使用 cookie 和会话。

drupal 站点的类似实现是在http://drupal.org/sandbox/sadashiv/1857254 的 Google OAuth2 沙箱中。此模块允许您处理来自 drupal 管理界面的身份验证。然后,您可以使用从 google 获取的访问令牌,然后使用 google_oauth2_account_load 或 google_oauth2_client_get 的 api 函数获取 Google_Client 并携带您的 api 调用。

【讨论】:

【参考方案3】:

与希望行业非常相似,但经过测试,我只想在必要时刷新令牌。完整源代码只需更改顶部的键等:

require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_CalendarService.php';
session_start();
$client = new Google_Client();
$client->setApplicationName("Google Calendar PHP Starter Application");
// Visit https://code.google.com/apis/console?api=calendar to generate your
// client id, client secret, and to register your redirect uri.
$client->setClientId('your_id');
$client->setClientSecret('your_secret');
$client->setRedirectUri("http://localhost/your_redirect.php");
$client->setDeveloperKey('your_key');

$cal = new Google_CalendarService($client);

if (isset($_GET['code'])) 
    $client->authenticate($_GET['code']);
    $_SESSION['token'] = $client->getAccessToken();
    header('Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'] . $query_string);


if (isset($_SESSION['token'])) 
    $client->setAccessToken($_SESSION['token']);//update token
    //json decode the session token and save it in a variable as object
    $sessionToken = json_decode($_SESSION['token']);
    //Save the refresh token (object->refresh_token) into a cookie called 'token' and make last for 1 month
    if (isset($sessionToken->refresh_token))  //refresh token is only set after a proper authorisation
        $number_of_days = 30 ;
        $date_of_expiry = time() + 60 * 60 * 24 * $number_of_days ;
        setcookie('token', $sessionToken->refresh_token, $date_of_expiry);
    

else if (isset($_COOKIE["token"])) //if we don't have a session we will grab it from the cookie
    $client->refreshToken($_COOKIE["token"]);//update token


if ($client->getAccessToken()) 
    $calList = $cal->calendarList->listCalendarList();
    print "<h1>Calendar List</h1><pre>" . print_r($calList, true) . "</pre>";
    $_SESSION['token'] = $client->getAccessToken();
 else 
    $authUrl = $client->createAuthUrl();
    print "<a class='login' href='$authUrl'>Select a calendar!</a>";

【讨论】:

以上是关于Google API Oauth php 永久访问的主要内容,如果未能解决你的问题,请参考以下文章

对新访问令牌的 PHP Google API OAuth2 JWT 请求显示“invalid_grant”

如何将 Google Services oAuth2 转换为 Google Ads API oAuth2 访问权限

需要Google OAuth 2.0架构建议通过Java邮件Api发送Smtp邮件

从 Google OAuth 2.0 PHP API 获取用户信息

哪些 Google 应用脚本 API 需要 OAuth 访问令牌?

无需 Oauth 令牌即可访问 Google 电子表格 API