php Google 客户端 API - 缺少需要参数:redirect_uri
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/34707227/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Google Client API - Missing require parameter: redirect_uri
提问by Joshua Blevins
So I followed the quickstartguide and decided to break it into a class called scheduler. I am working on the the authentication code, but I keep getting this: "Error 400 (OAuth 2 Error) Error Invalid Request Missing required Parameter: redirect_uri".
所以我遵循了快速入门指南,并决定将其分解为一个名为 scheduler 的类。我正在处理身份验证代码,但我不断收到此消息:“错误 400(OAuth 2 错误)错误无效请求缺少必需的参数:redirect_uri”。
class scheduler{
//The Google Client object
private $googleClient;
//the Google Calendar Service ojbect
private $calendarService;
/*
* Google Calendar Setup
*
* This creates a Google Client object so that you may create a Google Calendar object.
*
*/
function __construct(){
//set the application name
define("APPLICATION_NAME", "Web client 1");
//
define("CREDENTIALS_PATH", "~/scheduler/credentials.json");
//
define("CLIENT_SECRET_PATH", __DIR__ . "/scheduler/client_secret.json");
//
define("SCOPES", implode(" ", array(Google_Service_Calendar::CALENDAR_READONLY)));
/*if(php_sapi_name() != "cli"){
throw new Exception("This application must be run on the command line");
}*/
//create the google client
$this->googleClient = new Google_Client();
//setup the client
$this->googleClient->setApplicationName(APPLICATION_NAME);
$this->googleClient->setDeveloperKey("AIzaSyBmJLvNdMYuFhVpWalkUdyStrEBoVEayYM");
$this->googleClient->setScopes(SCOPES);
$this->googleClient->setAuthConfigFile(CLIENT_SECRET_PATH);
$this->googleClient->setAccessType("offline");
//get the credentials file path
$credentialsPath = expandHomeDirectory(CREDENTIALS_PATH);
//if the file exists
if(file_exists($credentialsPath)){
//get the credentials from the file
$accessToken = file_get_contents($credentialsPath);
}//if it does not
else{
//request the authorization url
$authURL = $this->googleClient->createAuthUrl();
//print the authorization ulr
echo "<a href=\"$authURL\">Press Me</a><br /><br />";
//prompt the user to enter the auth code
print("Enter authentication code: ");
//
$authCode = trim(fgets(STDIN));
//exchange authorization for an access token
$accessToken = $this->googleClient->authenticate($authCode);
//store credentials to disk
if(!file_exists(dirname($credentialsPath))){
mkdir(dirname($credentialsPath), 0700, true);
}
//put the contents into the credential files
file_put_contents($credentialsPath, $accessToken);
}
$this->googleClient->setAccessToken($accessToken);
//refresh token if its expired
if($this->googleClient->isAccessTokenExpired()){
$this->googleClient->refreshToken($client->getRefreshToken());
file_put_contents($credentialsPath, $this->googleClient->getAccessToken());
}
}
I found the cause of the problem with no solution in sight. Under my Google Developer Console I tried putting "http://localhost/" into the Authorized redirect URIs section. It gives me this error "Sorry, there's a problem. If you entered information, check it and try again. Otherwise, the problem might clear up on its own, so check back later." Is there a way to make Google Developer Console to accept the redirect uri of a localhost server?
我在看不到解决方案的情况下找到了问题的原因。在我的 Google Developer Console 下,我尝试将“ http://localhost/”放入 Authorized redirect URIs 部分。它给了我这个错误“对不起,有问题。如果您输入了信息,请检查并重试。否则,问题可能会自行解决,请稍后再回来查看。” 有没有办法让 Google Developer Console 接受本地主机服务器的重定向 uri?
采纳答案by Joshua Blevins
I got it to work. What I had to do was go back into Google Developer Console and delete the project I had created. Then when making a NEW project it allowed me to save my localhost url. The issue that was occuring was when I went to go add my localhost url to the redirect url it would say its not possible at this time. When I set the redirect url before hitting the create button it accepts it just fine.
我让它工作。我必须做的是返回 Google Developer Console 并删除我创建的项目。然后在创建一个新项目时,它允许我保存我的本地主机 URL。发生的问题是当我去将我的 localhost url 添加到重定向 url 时,它会说此时不可能。当我在点击创建按钮之前设置重定向 url 时,它接受它就好了。
回答by James07
Just use method setRedirectUri($absoluteUrl)
on a client object:
只需setRedirectUri($absoluteUrl)
在客户端对象上使用方法:
$client = new Google_Client();
$client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php');
via:
通过:
https://developers.google.com/api-client-library/php/auth/web-app
https://developers.google.com/api-client-library/php/auth/web-app
回答by Kevin Leary
Google's "PHP Quick Start" documentation for the Sheet API seems to be out of date at https://developers.google.com/sheets/api/quickstart/php.
Google 的 Sheet API 的“PHP 快速入门”文档在https://developers.google.com/sheets/api/quickstart/php 上似乎已过时。
To get their demo working with PHP 7.2+ I had to modify quite a bit, and it's not all that clear what's going on. Below is a commented, updated version of their quick start that may be helpful to anyone else having trouble working with the Google Sheets API and PHP.
为了让他们的演示与 PHP 7.2+ 一起工作,我不得不进行了相当多的修改,而且还不是很清楚发生了什么。下面是他们的快速入门的评论更新版本,可能对其他在使用 Google Sheets API 和 PHP 时遇到问题的人有所帮助。
<?php
/**
* Updated Google Sheets Quickstart
*
* https://developers.google.com/sheets/api/quickstart/php
*/
require __DIR__ . '/vendor/autoload.php';
/**
* Appends one slash at the end, and removes any extra slashes
* https://stackoverflow.com/a/9339669/812973
*
* @return string $path with the slash appended
*/
function addTrailingSlash ($path)
{
return rtrim ($path, '/') . '/';
}
/**
* Returns an authorized API client.
* @return Google_Client the authorized client object
*/
function getClient() {
// Change this to a secure location where you'll save your config *.json files
// Make sure it isn't publicly available on the web
$configPath = addTrailingSlash (getcwd());
// This get's generated by the script, so don't create it
$credentialsPath = $configPath . 'credentials.json';
$client = new Google_Client();
// Matches the "Application Name" you enter during the "Step 1" wizard
$client->setApplicationName( 'API App Name' );
$client->setScopes( Google_Service_Sheets::SPREADSHEETS_READONLY );
// You need to go through "Step 1" steps to generate this file: https://developers.google.com/sheets/api/quickstart/php
$client->setAuthConfig( $configPath . 'client_secret.json' );
$client->setAccessType( 'offline' );
// This must match the "callback URL" that you enter under "OAuth 2.0 client ID" in the Google APIs console at https://console.developers.google.com/apis/credentials
$client->setRedirectUri( 'https://' . $_SERVER['HTTP_HOST'] . '/' . basename( __FILE__, '.php' ) );
// We have a stored credentials file, try using the data from there first
if ( file_exists( $credentialsPath ) ) {
$accessToken = json_decode( file_get_contents( $credentialsPath ), true );
}
// No stored credentials found, we'll need to request them with OAuth
else {
// Request authorization from the user
$authUrl = $client->createAuthUrl();
if ( ! isset( $_GET['code'] ) ) {
header( "Location: $authUrl", true, 302 );
exit;
}
// The authorization code is sent to the callback URL as a GET parameter.
// We use this "authorization code" to generate an "access token". The
// "access token" is what's effectively used as a private API key.
$authCode = $_GET['code'];
$accessToken = $client->fetchAccessTokenWithAuthCode( $authCode );
// Create credentials.json if it doesn't already exist (first run)
if ( ! file_exists( dirname( $credentialsPath ) ) ) {
mkdir( dirname( $credentialsPath ), 0700, true );
}
// Save the $accessToken object to the credentials.json file for re-use
file_put_contents( $credentialsPath, json_encode( $accessToken ) );
}
// Provide client with API access token
$client->setAccessToken( $accessToken );
// If the $accessToken is expired then we'll need to refresh it
if ( $client->isAccessTokenExpired() ) {
$client->fetchAccessTokenWithRefreshToken( $client->getRefreshToken() );
file_put_contents( $credentialsPath, json_encode( $client->getAccessToken() ) );
}
return $client;
}
// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Sheets( $client );
// Get values from a spreadheet and print
// https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/get
$spreadsheetId = '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms';
$range = 'Class Data!A2:E';
$response = $service->spreadsheets_values->get($spreadsheetId, $range);
$values = $response->getValues();
if (empty($values)) {
print "No data found.\n";
} else {
print "Name, Major:\n";
foreach ($values as $row) {
// Print columns A and E, which correspond to indices 0 and 4.
printf("%s, %s\n", $row[0], $row[4]);
}
}
回答by H A?d?μ
Just improving the answer of @kevinLeary so the code can looks more modular:
只是改进@kevinLeary 的答案,使代码看起来更加模块化:
<?php
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
throw new Exception(sprintf('Please run "composer require google/apiclient:~2.0" in "%s"', __DIR__));
}
require_once __DIR__ . '/vendor/autoload.php';
$redirect_url = 'http://' . $_SERVER['HTTP_HOST'] . '/mydrive/index.php'; // <--- Change it to your web application path, host will be detected automatically
$auth_file = __DIR__ . DIRECTORY_SEPARATOR . 'drive-auth.json'; // <--- Your auth2 settings
$auth_file = str_replace('\', '/', $auth_file);
$configPath = addTrailingSlash(getcwd());
$credentials_file = $configPath . 'credentials.json'; // <--- This will generated automatically
$app_name = 'MY APP NAME';
$scopes = [
Google_Service_Sheets::SPREADSHEETS_READONLY,
];
/**
* Returns an authorized API client.
* @return Google_Client the authorized client object
*/
function getClient($app_name, $auth_file, $credentials_file, $redirect_url, $scopes = array()) {
// This get's generated by the script, so don't create it
$credentialsPath = $credentials_file;
$client = new Google_Client();
// Matches the "Application Name" you enter during the "Step 1" wizard
$client->setApplicationName( $app_name );
$client->setScopes( $scopes );
// You need to go through "Step 1" steps to generate this file: https://developers.google.com/sheets/api/quickstart/php
$client->setAuthConfig( $auth_file );
$client->setAccessType( 'offline' );
// This must match the "callback URL" that you enter under "OAuth 2.0 client ID" in the Google APIs console at https://console.developers.google.com/apis/credentials
$client->setRedirectUri( $redirect_url );
// We have a stored credentials file, try using the data from there first
if ( file_exists( $credentialsPath ) ) {
$accessToken = json_decode( file_get_contents( $credentialsPath ), true );
}
// No stored credentials found, we'll need to request them with OAuth
else {
// Request authorization from the user
$authUrl = $client->createAuthUrl();
if ( ! isset( $_GET['code'] ) ) {
header( "Location: $authUrl", true, 302 );
exit;
}
// The authorization code is sent to the callback URL as a GET parameter.
// We use this "authorization code" to generate an "access token". The
// "access token" is what's effectively used as a private API key.
$authCode = $_GET['code'];
$accessToken = $client->fetchAccessTokenWithAuthCode( $authCode );
// Create credentials.json if it doesn't already exist (first run)
if ( ! file_exists( dirname( $credentialsPath ) ) ) {
mkdir( dirname( $credentialsPath ), 0700, true );
}
// Save the $accessToken object to the credentials.json file for re-use
file_put_contents( $credentialsPath, json_encode( $accessToken ) );
}
// Provide client with API access token
$client->setAccessToken( $accessToken );
// If the $accessToken is expired then we'll need to refresh it
if ( $client->isAccessTokenExpired() ) {
$client->fetchAccessTokenWithRefreshToken( $client->getRefreshToken() );
file_put_contents( $credentialsPath, json_encode( $client->getAccessToken() ) );
}
return $client;
}
// Get the API client and construct the service object.
$client = getClient();
$service = new Google_Service_Sheets( $client );
// Get values from a spreadheet and print
// https://developers.google.com/sheets/api/reference/rest/v4/spreadsheets.values/get
$spreadsheetId = '1BxiMVs0XRA5nFMdKvBdBZjgmUUqptlbs74OgvE2upms';
$range = 'Class Data!A2:E';
$response = $service->spreadsheets_values->get($spreadsheetId, $range);
$values = $response->getValues();
if (empty($values)) {
print "No data found.\n";
} else {
print "Name, Major:\n";
foreach ($values as $row) {
// Print columns A and E, which correspond to indices 0 and 4.
printf("%s, %s\n", $row[0], $row[4]);
}
}
function addTrailingSlash ($path)
{
return rtrim ($path, '/') . '/';
}
?>