我正在尝试使用Gmail API访问网络应用程序中的电子邮件。我在https://developers.google.com/gmail/api/quickstart/php尝试过这个例子并且工作正常。现在我想使用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.
});
当我在php脚本中手动添加来自javascript API的响应时,它显示错误
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 :(得分: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客户端库管理;那你去...我希望这有帮助!