2017-02-18 118 views
2

我試圖在PHP中使用Google Calendar API來訪問一箇中央帳戶。這個想法是,其他用戶可以添加事件到這個中央帳戶(他們不必登錄谷歌帳戶),所以我想永久訪問該帳戶。Google Calendar API,PHP獲取刷新令牌失敗

首先,我做了Quickstart tutorial on Google's webpage。我登錄了我的帳戶,一切都在工作一段時間。後來,我的訪問令牌已過期,現在,$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());拋出LogicException:刷新令牌必須傳入或設置爲setAccessToken的一部分。我發現$client->getRefreshToken()返回null。

在這裏你可以看到我的整個代碼來獲得在谷歌客戶:

$client = new Google_Client(); 
$client->setApplicationName('Google Calendar API PHP Quickstart'); 
$client->setScopes(implode(' ', array(Google_Service_Calendar::CALENDAR))); 
$client->setAuthConfig(__DIR__ . '/../config/client_secret.json'); 
$client->setAccessType('offline'); 

$credentialsPath = __DIR__ . '/../config/calendar-php-quickstart.json'; 
$accessToken = json_decode(file_get_contents($credentialsPath), true); 
$client->setAccessToken($accessToken); 

// Refresh the token if it's expired. 
if ($client->isAccessTokenExpired()) { 
    $client->fetchAccessTokenWithRefreshToken($client->getRefreshToken()); 
    file_put_contents($credentialsPath, json_encode($client->getAccessToken())); 
} 

任何想法,我究竟做錯了什麼?

回答

0

嘗試使用DalmTo的教程關於Calendar API and service accounts

這是她的指導刷新令牌實現:

$client->setAssertionCredentials($cred); 
if($client->getAuth()->isAccessTokenExpired()) {  
    $client->getAuth()->refreshTokenWithAssertion($cred); 
} 
0

您可以測試下面的代碼:

    // Refresh the token if it's expired. 
        if ($client->isAccessTokenExpired()) { 
         // save refresh token to some variable 
         $refreshTokenSaved = $client->getRefreshToken(); 

         // update access token 
         $client->fetchAccessTokenWithRefreshToken($refreshTokenSaved); 

         // pass access token to some variable 
         $accessTokenUpdated = $client->getAccessToken(); 

         // append refresh token 
         $accessTokenUpdated['refresh_token'] = $refreshTokenSaved; 

         // save to file 
         file_put_contents($credentialsPath, json_encode($accessTokenUpdated)); 
        } 
0

我會分享我的代碼,我終於得到了工作。我正在使用前端Web應用程序來獲得初始授權,然後將該代碼傳遞給PHP Web服務以存儲在dbase中供以後使用。

<?php 
require_once 'vendor/autoload.php'; 

/** 
class to provide google calendar api functions. 
returns information to mobile web app in json format 
**/ 
class Calendar 
{ 

    private $client; 
    private $clientsecretgoogle = '{input secret here}'; 
    private $clientIDgoogle = '{input client ID here}'; 
    private $objDatabase; 
    private $queryParams; 
    private $params; 

    public function __construct($params) 
    { 

     $this->client = new Google_Client(); 
     $this->client->setClientId($this->clientIDgoogle); 
     $this->client->setClientSecret($this->clientsecretgoogle); 
     $this->client->setAccessType('offline'); //this seems to be important for refresh tokens to update 
     $this->objDatabase = new Database();//connect to dbase 
     $this->params=$params; 

    } 

    public function getAuthorizationRefreshTokensGoogle($authCode, $userID) 
    { 

     /* 
     Get access_token and refresh token from returned auth code 
     I'm getting this on the front end and then storing in dbase table 
     Could have used the basic php library here but this worked so I stuck with it 
     */ 
     $oauth_url = 'https://www.googleapis.com/oauth2/v4/token?code=' . $authCode . '&client_secret=' . $this->clientsecretgoogle . '&client_id=' . $this->clientIDgoogle . '&redirect_uri=postmessage&grant_type=authorization_code'; 
     //using curl 
     $ch = curl_init(); 
     curl_setopt($ch, CURLOPT_URL, $oauth_url); 
     curl_setopt($ch, CURLOPT_POST, 1); 
     curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 
     $return = curl_exec($ch); 

     curl_close($ch); 
     $return = json_decode($return); 
     // You can dump the vars to see the object 
     //var_dump($return); 

     //insert into table for later retrieval 
     $strSQL = "insert ignore into tbloauth(oauth_usr_id,oauth_vendor,oauth_token,oauth_refresh_token,oauth_token_expire)VALUES 
       (?,?,?,?,?)"; 
     //check for existence of refresh token in response 
     //if not there then replace only the access_token 
     //if there then replace access, refresh 
     if(!$return->refresh_token){ 
      $strSQL .= "ON DUPLICATE KEY UPDATE oauth_token=VALUES(oauth_token), oauth_token_expire=VALUES(oauth_token_expire)"; 
     }else{ 
      $strSQL .= "ON DUPLICATE KEY UPDATE oauth_token=VALUES(oauth_token),oauth_refresh_token=VALUES(oauth_refresh_token), oauth_token_expire=VALUES(oauth_token_expire)"; 
     } 
     //translate expire time NOW + 3600 
     $expire = (time() + $return->expires_in); 
     if (!$return->refresh_token) { 
      $return->refresh_token = ''; 
     } 

     $this->queryParams = array($userID, 'google', $return->access_token, $return->refresh_token, $expire); 
     $this->objDatabase->insertQuery($strSQL, $this->queryParams); 

     //you should now have a record now containing the access_token,refresh token, expire date 

    } 

    /* 

    List calendars 
    */ 
    function listCalendarsGoogle() 
    { 

     //1. Get tokens from database for the current user 
     $result=$this->getUserAccessToken($this->params['usr_id'],'google'); 
     //2. Set access token with returned results 
     $this->client->setAccessToken(json_encode($result[0])); 

     //check for expired token and refresh if necessary 
     if($this->client->isAccessTokenExpired()) { 
      $this->client->refreshToken($result[0]['oauth_refresh_token']); 
      $access_token = $this->client->getAccessToken(); 
      $strSQL="update tbloauth set oauth_token=? where oauth_vendor='google' and oauth_usr_id=? limit 1"; 
      $this->queryParams=array($access_token,$this->params['usr_id']); 
      $this->objDatabase->updateQuery($strSQL,$this->queryParams); 

     } 

     //3.init calendar 
     $calendar = new Google_Service_Calendar($this->client); 

     //4. list calendars of primary 
     $calendarList = $calendar->calendarList->listCalendarList('primary'); 


     return json_encode($calendarList); 


    } 
    /** 
    get access token for vendor(google in this case) using usr_id of user 
    which is passed to the class from the web app 

    */ 
    public function getUserAccessToken($usr_id,$vendor){ 

     $strSQL="select tbloauth.*,oauth_token as access_token,oauth_refresh_token as refresh_token from tbloauth where oauth_usr_id=? and oauth_vendor=? "; 
     $this->queryParams=array($usr_id,$vendor); 
     //echo $this->objDatabase->parms($strSQL,$this->queryParams); 
     $aResult=$this->objDatabase->selectQuery($strSQL,$this->queryParams); 
     $aResult[0]['client_id']=$this->clientIDgoogle; 
     $aResult[0]['client_secret']=$this->clientsecretgoogle; 
     return $aResult; 


    } 
    /** 
    Insert Event into google using event info posted by web app 

    */ 
    public function insertEventGoogle(){ 

     $result=$this->getUserAccessToken($this->params['usr_id'],'google'); 
     $this->client->setAccessToken(json_encode($result[0])); 
     //check if expired 
     //if expired then fetch new token with current token 
     //update dbase with new token 
     //this would be cleaner separated into another method 
     //called before each list or insert calendar function 

     if($this->client->isAccessTokenExpired()) { 
      $this->client->refreshToken($result[0]['oauth_refresh_token']); 
      $access_token = $this->client->getAccessToken(); 
      $strSQL="update tbloauth set oauth_token=? where oauth_vendor='google' and oauth_usr_id=? limit 1"; 
      $this->queryParams=array($access_token,$this->params['usr_id']); 
      $this->objDatabase->updateQuery($strSQL,$this->queryParams); 

     } 

     //init calendar 
     $calendar = new Google_Service_Calendar($this->client); 
     //event info 
     $event = new Google_Service_Calendar_Event(array(
      'summary' => $this->params['event_name'], 
      'location' => $this->params['event_location'], 
      'description' => $this->params['event_desc'], 
      'start' => array(
       'dateTime' => date(DATE_ISO8601, strtotime($this->params['event_start_date'].' '.$this->params['event_start_time'])), 
       'timeZone' => 'America/New_York', 
      ), 
      'end' => array(
       'dateTime' => date(DATE_ISO8601, strtotime($this->params['event_end_date'].' '.$this->params['event_end_time'])), 
       'timeZone' => 'America/New_York', 
      ), 
      'reminders' => array(
       'useDefault' => FALSE, 
       'overrides' => array(
        array('method' => 'email', 'minutes' => 24 * 60), 
        array('method' => 'popup', 'minutes' => 10), 
       ), 
      ), 
     )); 
     //calendar id - default primary 
     $calendarId = 'primary'; 
     //insert event 
     $event = $calendar->events->insert($calendarId, $event); 
     //return confirm msg 
     $msg=array('msg'=>'Event Created: '.$this->params['event_name']); 
     return json_encode($msg); 





    } 
} 

希望能幫助別人。文件很難整理。