2017-10-13 406 views
0

我正嘗試使用Gmail API訪問Web應用程序中的電子郵件。我試過在https://developers.google.com/gmail/api/quickstart/php的例子,工作正常。現在我想要使用JavaScript API獲取訪問令牌並在上例中使用。使用Google javascript API進行身份驗證

gapi.auth2.authorize({ 
    client_id: 'CLIENT_ID.apps.googleusercontent.com', 
    scope: 'email profile openid', 
    response_type: 'id_token permission' 
}, function(response) { 
    if (response.error) { 
    // An error happened! 
    return; 
    } 
    // The user authorized the application for the scopes requested. 
    var accessToken = response.access_token; 
    var idToken = response.id_token; 
    // You can also now use gapi.client to perform authenticated requests. 
}); 

當我手動添加從JavaScript API中的PHP腳本的響應它顯示錯誤

Uncaught exception 'LogicException' with message 'refresh token must be passed in or set as part of setAccessToken' in D:\wamp\www\gmailexample\google-api-php-client-2.2.0\src\Google\Client.php:267 

下面是我使用的PHP腳本。

<?php 
require_once '/google-api-php-client-2.2.0/vendor/autoload.php'; 


define('APPLICATION_NAME', 'Gmail API PHP Quickstart'); 
define('CREDENTIALS_PATH', '~/.credentials/gmail-php-quickstart.json'); 
define('CLIENT_SECRET_PATH', 'client_secret.json'); 
// If modifying these scopes, delete your previously saved credentials 
// at ~/.credentials/gmail-php-quickstart.json 
define('SCOPES', implode(' ', array(
    Google_Service_Gmail::GMAIL_READONLY) 
)); 

if (php_sapi_name() != 'cli') { 
    throw new Exception('This application must be run on the command line.'); 
} 

/** 
* Returns an authorized API client. 
* @return Google_Client the authorized client object 
*/ 
function getClient() { 
    $client = new Google_Client(); 
    $client->setApplicationName(APPLICATION_NAME); 
    $client->setScopes(SCOPES); 
    $client->setAuthConfig(CLIENT_SECRET_PATH); 
    $client->setAccessType('offline'); 

    // Load previously authorized credentials from a file. 
    $credentialsPath = expandHomeDirectory(CREDENTIALS_PATH); 

    $accessToken= json_decode('{"access_token":"asdfsasdfsasdfsasdfs","expires_in":2255,"expires_at":254877}', 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())); 
    } 
    return $client; 
} 

/** 
* Expands the home directory alias '~' to the full path. 
* @param string $path the path to expand. 
* @return string the expanded path. 
*/ 
function expandHomeDirectory($path) { 
    $homeDirectory = getenv('HOME'); 
    if (empty($homeDirectory)) { 
    $homeDirectory = getenv('HOMEDRIVE') . getenv('HOMEPATH'); 
    } 
    return str_replace('~', realpath($homeDirectory), $path); 
} 

// Get the API client and construct the service object. 
$client = getClient(); 
$service = new Google_Service_Gmail($client); 

// Print the labels in the user's account. 
$user = 'me'; 
$results = $service->users_labels->listUsersLabels($user); 

if (count($results->getLabels()) == 0) { 
    print "No labels found.\n"; 
} else { 
    print "Labels:\n"; 
    foreach ($results->getLabels() as $label) { 
    printf("- %s\n", $label->getName()); 
    } 
} 

請大家幫忙。

+0

你可以請顯示什麼是你的PHP腳本? – Morfinismo

+0

@Morfinismo我用php腳本更新了這個問題。 – user1690835

回答

1

好吧,我的朋友,這是你的解決方案。爲了確保你理解這一點,我做了一個例子。首先,在你的工作目錄中,確保你有Google PHP客戶端庫和其他兩個文件。第一個應該被稱爲的index.php和下面的代碼粘貼文件中:

<html> 

    <head> 

    <title>JS/PHP Google Sample</title> 

    <script src="https://code.jquery.com/jquery-3.2.1.min.js" integrity="sha256-hwg4gsxgFZhOsEEamdOYGBf13FyQuiTwlAQgxVSNgt4=" crossorigin="anonymous"></script> 

    <script type="text/javascript"> 

     function handleClientLoad() { 
     // Loads the client library and the auth2 library together for efficiency. 
     // Loading the auth2 library is optional here since `gapi.client.init` function will load 
     // it if not already loaded. Loading it upfront can save one network request. 
     gapi.load('client:auth2', initClient); 
     } 

     function initClient() { 
     // Initialize the client with API key and People API, and initialize OAuth with an 
     // OAuth 2.0 client ID and scopes (space delimited string) to request access. 
     gapi.client.init({ 
      apiKey: 'YOUR API KEY GOES HERE', 
      clientId: 'YOUR CLIENT ID GOES HERE', 
      scope: 'email profile https://www.googleapis.com/auth/gmail.readonly', 
     }).then(function() { 
      // Listen for sign-in state changes. 
      gapi.auth2.getAuthInstance().isSignedIn.listen(updateSigninStatus); 

      // Handle the initial sign-in state. 
      updateSigninStatus(gapi.auth2.getAuthInstance().isSignedIn.get()); 
     }); 
     } 

     function updateSigninStatus(isSignedIn) { 
     // When signin status changes, this function is called. 
     // If the signin status is changed to signedIn, we make an API call. 
     if (isSignedIn) { 
      $("#signout-button").show(); 
      $("#signin-button").hide(); 
      makeApiCall(); 
     } else { 
      $("#signin-button").show(); 
      $("#signout-button").hide(); 
     } 
     } 

     function handleSignInClick(event) { 
     // Ideally the button should only show up after gapi.client.init finishes, so that this 
     // handler won't be called before OAuth is initialized. 
     gapi.auth2.getAuthInstance().signIn(); 
     } 

     function handleSignOutClick(event) { 
     var host = "http://"+window.location.hostname; 
     gapi.auth2.GoogleUser.prototype.disconnect(); 
     window.open(host, "_self"); 
     } 

     function makeApiCall() { 
     // Make an API call to the People API, and print the user's given name.  
     var accsTkn = gapi.auth2.getAuthInstance().$K.Q7.access_token;  
     var formData = new FormData(); 
     formData.append("access_token", accsTkn); //send access token 

     $.ajax({ 
      url : 'listEmails.php', 
      type : 'POST', 
      data : formData, 
      processData: false, // tell jQuery not to process the data 
      contentType: false, // tell jQuery not to set contentType 
      success : function(html) { 

       $("#myLabels").append(html); 

      } 
     }); 

     } 

    </script> 

    <style> 

     #signin-button{ 
      display: none; 
     } 

     #signout-button{ 
      display: none; 
     } 

     #myLabels{ 
      width: 80%; 
      min-height: 350px; 
     } 

    </style> 


    </head> 

    <body> 

    <center> 

     <h1>Google OAuth Gmail Example with Javascript and PHP</h1><br> 

     <button id="signin-button" onclick="handleSignInClick()">Sign In</button> 

     <br><br><br> 

     <div id="myLabels"> 
      Emails list: <br><br> 

     </div>  

     <br><br> 
     <button id="signout-button" onclick="handleSignOutClick()">Sign Out</button> 

    </center> 


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

    </body> 

</html> 

接下來,第二個文件應該被命名爲listEmails.php並粘貼以下代碼中:

<?php session_start();  

require_once "path_to_php_client_lib/vendor/autoload.php"; //include php client library 

//set the required parameteres 
$scopes = array("https://www.googleapis.com/auth/gmail.readonly"); 

$client = new Google_Client(); 
$client->setRedirectUri('http://'.$_SERVER['HTTP_HOST'].'listEmails.php'); 
$client->setAuthConfig("client_secret.json"); 
$client->addScope($scopes); 

$client->setAccessToken($_POST["access_token"]); 
$service = new Google_Service_Gmail($client); // define service to be rquested 

$pageToken = NULL; 
$messages = array(); 
$opt_param = array("maxResults" => 5); 

try { 
    $messagesResponse = $service->users_messages->listUsersMessages("me", $opt_param); 
    if ($messagesResponse->getMessages()) { 
    $messages = array_merge($messages, $messagesResponse->getMessages()); 
    } 
} catch (Exception $e) { 
    print 'An error occurred: ' . $e->getMessage(); 
} 

foreach ($messages as $message) { 
    $msgId = $message->getId(); 
    $optParams = array("format" => "full"); 
    $uniqueMsg = $service->users_messages->get("me", $msgId, $optParams); 
    print 'Message with ID: ' . $uniqueMsg->id . '<br>'; 
    print 'Message From: ' . $uniqueMsg->getPayload()->getHeaders()[18]->value . '<br><br>**************************<br><br>'; 
} 


?> 

理解例如: 文檔here清楚地解釋

此OAuth 2.0流稱爲隱式授權流。它專爲僅在用戶在應用程序時訪問API的應用程序而設計。這些應用程序無法存儲機密信息。

這意味着使用Javascript身份驗證流程將無法獲得脫機訪問權限。考慮到這一點,我們可以繼續前進。

正如你可以看到在PHP腳本,你不需要刷新令牌,因爲這將由Javascript客戶端庫管理;在那裏你去...我希望這有助於!

+0

謝謝。你保存了一天。 – user1690835

+0

但仍然JavaScript API不提供刷新令牌。所以PHP腳本在令牌過期一小時後會拋出相同的錯誤。 – user1690835

+0

我試着用這裏的例子https://developers.google.com/identity/sign-in/web/server-side-flow。但是當我將代碼粘貼到php腳本中時,會得到$ accessToken = $ client-> fetchAccessTokenWithAuthCode($ authCode);正在給出響應數組 ( [error] => unauthorized_client [error_description] =>未授權 ) – user1690835

相關問題