I was attempting a google sign in using the following code:
<code>
function gLogin(){ //handle the login process for retrieving google User's email with
$client = new Google_Client();
$client->setAuthConfig(CLIENT_SECRET_PATH);
$client->setScopes(array(Google_Service_Oauth2::USERINFO_EMAIL,Google_Service_Oauth2::USERINFO_PROFILE,Google_Service_Plus::PLUS_ME,Google_Service_Plus::PLUS_LOGIN));
$plus = new Google_Service_Plus($client);
try{
$client->authenticate($_GET['code']);
$me = $plus->people->get('me');
//deal with non-domain Emails
if($me['domain'] !== 'xxx.org' && $me['domain'] !== 'xxx.org'){
$client->revokeToken();
$errorUrl = ERROR_URI . '?error=wrongDomain';
http_response_code(302);
header('Location: ' . $errorUrl);
die();
}
$displayName = $me['displayName'];
//get the email
$oauth = new Google_Service_Oauth2($client);
$emails = $oauth->userinfo->get();
$email = $emails->getEmail();
//too nested, going to sqlLogin
sqlLogin($email, $displayName);
$client->revokeToken();
}catch(Exception $e){
error_log($e->getMessage());
}
}
</code>
When I did, I would get the following error:
{\n "error": {\n "errors": [\n {\n "domain": "usageLimits",\n
"reason": "dailyLimitExceededUnreg",\n "message": "Daily Limit for
Unauthenticated Use Exceeded. Continued use requires signup.",\n
"extendedHelp": "https://code.google.com/apis/console"\n }\n ],\n
"code": 403,\n "message": "Daily Limit for Unauthenticated Use
Exceeded. Continued use requires signup."\n }\n}\n,
Any help would be appreciated
I realized my own error. Since I was redirecting from index.php and not keeping the access token, I had to manually set it with $client->setAccessToken($client->getAccessToken()); (I wasn't keeping the token due to some code standardization that I wanted). Updated code:
$client = new Google_Client();
$client->setAuthConfig(CLIENT_SECRET_PATH);
$client->setRedirectUri('replace_me'); //not sure if I need the redirectUri here, but it was one of the things I tested
$client->setScopes(array(Google_Service_Oauth2::USERINFO_EMAIL,Google_Service_Oauth2::USERINFO_PROFILE,Google_Service_Plus::PLUS_ME,Google_Service_Plus::PLUS_LOGIN));
try{
$error = $client->authenticate($_GET['code']);
print_r($error);
$client->setAccessToken($client->getAccessToken()); /*access tokens must be requested with the following line if you are not keeping them, otherwise it will be an unauthenticated request*/
$plus = new Google_Service_Plus($client);
$me = $plus->people->get('me');
//deal with non-domain Emails
if($me['domain'] !== 'xxx.org' && $me['domain'] !== 'xxx.org'){
$client->revokeToken();
$errorUrl = ERROR_URI . '?error=notDomain';
http_response_code(302);
header('Location: ' . $errorUrl);
die();
}
$displayName = $me['displayName'];
//get the email
$oauth = new Google_Service_Oauth2($client);
$emails = $oauth->userinfo->get();
$email = $emails->getEmail();
//too nested, going to sqlLogin
sqlLogin($email, $displayName);
$client->revokeToken();
}catch(Exception $e){
error_log($e->getMessage()); }
Related
This is the code I have and it does not work for me, it returns the error commented on the subject. I have done the whole process by registering, delegating the entire domain and authorizing everything and it fails...
$REDIRECT_URI = 'https://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
$KEY_LOCATION = $_SERVER['DOCUMENT_ROOT'].'/cada/includes/classes/google-api-php-client-2.1.1/client_secret_1050007893675-7bkmqjiqr1p57s9alr7fu7e016lrh5hc.apps.googleusercontent.com.json';
$TOKEN_FILE = $_SERVER['DOCUMENT_ROOT']."/cada/share/token.txt";
$SCOPES = array(
Google_Service_Calendar::CALENDAR
);
$client = new Google_Client();
$client->setApplicationName("SimesatSat");
$client->setAuthConfig($KEY_LOCATION);
// Incremental authorization
$client->setIncludeGrantedScopes(true);
// Allow access to Google API when the user is not present.
$client->setAccessType('offline');
$client->setRedirectUri($REDIRECT_URI);
$client->setScopes($SCOPES);
if (isset($_GET['code']) && !empty($_GET['code']))
{
try
{
// Exchange the one-time authorization code for an access token
$accessToken = $client->fetchAccessTokenWithAuthCode($_GET['code']);
// Save the access token and refresh token in local filesystem
file_put_contents($TOKEN_FILE, json_encode($accessToken));
$_SESSION['accessToken'] = $accessToken;
header('Location: ' . filter_var($REDIRECT_URI, FILTER_SANITIZE_URL));
exit();
}
catch (\Google_Service_Exception $e)
{
print_r($e);
}
}
if (!isset($_SESSION['accessToken']))
{
$token = #file_get_contents($TOKEN_FILE);
if ($token == null)
{
// Generate a URL to request access from Google's OAuth 2.0 server:
$authUrl = $client->createAuthUrl();
// Redirect the user to Google's OAuth server
header('Location: ' . filter_var($authUrl, FILTER_SANITIZE_URL));
exit();
}
else
{
$_SESSION['accessToken'] = json_decode($token, true);
}
}
$client->setAccessToken($_SESSION['accessToken']);
/* Refresh token when expired */
if ($client->isAccessTokenExpired())
{
// the new access token comes with a refresh token as well
$client->fetchAccessTokenWithRefreshToken($client->getRefreshToken());
file_put_contents($TOKEN_FILE, json_encode($client->getAccessToken()));
}
////////////CONSULTA DATOS ////////////////////////////
$service = new Google_Service_Calendar($client);
$results = $service->calendarList->listCalendarList();
print_r($results);
Can anybody help me? I have another project with another client with the same code and it works perfectly! I do not understand what's happening. The only difference is that this project is part of a subdomain. Could that be the mistake?
I want to upload a video on YouTube via php. To do this, I've followed this tutorial to get the rights (authenticate) and this to upload the video.
The authentication works as it should. The user is redirected to a google site, accepts that I have a right upload YouTube videos, etc. and is redirected to my site again. There, the access token is saved.
But if I want to upload a video, I get this error:
A service error occurred: { "error": { "errors": [ { "domain": "global", "reason": "authError", "message": "Invalid Credentials", "locationType": "header", "location": "Authorization" } ], "code": 401, "message": "Invalid Credentials" } }
To test my application, I've tried to retrieve my uploads instead of uploading a video, but the same error occurred.
I have no idea what triggers this error.
Here is my code from the site which redirects the user to google:
$OAUTH2_CLIENT_ID = "Not on Stackoverflow (but here is a code)";
$OAUTH2_CLIENT_SECRET = "Also not on Stackoverflow";
$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
$client->addScope("https://www.googleapis.com/auth/youtube.upload");
$client->addScope("https://www.googleapis.com/auth/youtube");
$client->setRedirectUri("my site(actual link)");
$client->setAccessType('offline'); // offline access
$client->setIncludeGrantedScopes(true); // incremental auth
$auth_url = $client->createAuthUrl();
echo 'Allow posting on YouTube (click)';
Here is my code from the site the user is redirected to from Google:
$OAUTH2_CLIENT_ID = "Not on Stackoverflow (but here is a code)";
$OAUTH2_CLIENT_SECRET = "Also not on Stackoverflow";
$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
$client->addScope("https://www.googleapis.com/auth/youtube.upload");
$client->addScope("https://www.googleapis.com/auth/youtube");
$client->setRedirectUri("my site (actual link)");
$client->setAccessType('offline'); // offline access
$client->setIncludeGrantedScopes(true); // incremental auth
$client->authenticate($_GET['code']);
$access_token = $client->getAccessToken();
//Acces token is being saved
And here is the upload code (which doesn't work):
$OAUTH2_CLIENT_ID = "--";
$OAUTH2_CLIENT_SECRET = "--";
$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
$client->addScope("https://www.googleapis.com/auth/youtube.upload");
$client->addScope("https://www.googleapis.com/auth/youtube");
$client->setRedirectUri("https://www.socialme.online/YoutubeFT.php");
$client->setAccessType('offline'); // offline access
$client->setIncludeGrantedScopes(true); // incremental auth
$client->setAccessToken($access_token);
$youtube = new Google_Service_YouTube($client);
try {
$snippet = new Google_Service_YouTube_VideoSnippet();
$snippet->setTitle($Titel);
$snippet->setDescription($Beschreibung);
$snippet->setTags(array("tag1", "tag2"));
$snippet->setCategoryId("22");
$status = new Google_Service_YouTube_VideoStatus();
$status->privacyStatus = "public";
$video = new Google_Service_YouTube_Video();
$video->setSnippet($snippet);
$video->setStatus($status);
$chunkSizeBytes = 1048576;
$client->setDefer(true);
$insertRequest = $youtube->videos->insert("status,snippet", $video);
$media = new Google_Http_MediaFileUpload(
$client,
$insertRequest,
'video/'.$extension,
null,
true,
$chunkSizeBytes
);
$media->setFileSize(filesize($new_path));
// Read the media file and upload it chunk by chunk.
$status = false;
$handle = fopen($new_path, "rb");
while (!$status && !feof($handle)) {
$chunk = fread($handle, $chunkSizeBytes);
$status = $media->nextChunk($chunk);
}
fclose($handle);
$client->setDefer(false);
} catch (Google_Service_Exception $e) {
$htmlBody .= sprintf('<p>A service error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
} catch (Google_Exception $e) {
$htmlBody .= sprintf('<p>An client error occurred: <code>%s</code></p>',
htmlspecialchars($e->getMessage()));
}
echo $htmlBody;
I've no idea what causes this error, especially as most code is taken from the official Google documents. The URL in redirect_uri is valid and the same as the one, authorised in the Google Console. The link to the video is valid, too.
Thank you for your help.
I am trying to implement a log in via Google on my application to access some information and control some features of the user Youtube channel but it is returning error all the time, saying that the user is not authenticated.
That's my code.
<?php
session_start();
ini_set('display_errors', 1);
error_reporting(E_ALL);
require_once 'vendor/autoload.php';
$OAUTH2_CLIENT_ID = '-----------------------------------------';
$OAUTH2_CLIENT_SECRET = '-----------------';
$REDIRECT = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$APPNAME = "Test";
try{
$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
$client->setScopes([
'https://www.googleapis.com/auth/youtube.force-ssl',
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/plus.me',
'https://www.googleapis.com/auth/userinfo.profile'
]);
$client->setRedirectUri($REDIRECT);
$client->setApplicationName($APPNAME);
$client->setDeveloperKey('---------------------');
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
}
catch(Exception $e){
die('1: '.$e);
}
$youtube = new Google_Service_YouTube($client);
$google_oauth = new Google_Service_Oauth2($client);
$plusAuth = new Google_Service_Plus($client);
if (isset($_GET['code'])) {
if (strval($_SESSION['state']) !== strval($_GET['state'])) {
die('The session state did not match.');
}
try{
$client->authenticate($_GET['code']);
$user_email = $google_oauth->userinfo->get()->email;
$user_name = $plusAuth->people->get('me')->displayName;
}
catch(Exception $e){
die('2: '.$e);
}
// Code in between
$_SESSION['token'] = $client->getAccessToken();
}
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
//echo "Access Token: " . json_encode($_SESSION['token']);
header('Location: /main.php');
}
if ($client->getAccessToken()) {
$_SESSION['token'] = $client->getAccessToken();
}
else{
$state = mt_rand();
$client->setState($state);
$_SESSION['state'] = $state;
header('Location: '.$client->createAuthUrl());
}
?>
And I am getting this error:
2: Google_Service_Exception: { "error": { "code": 401, "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.", "errors": [ { "message": "Request is missing required authentication credential. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.", "domain": "global", "reason": "unauthorized" } ], "status": "UNAUTHENTICATED" } }
I can't find the reason to the login flow is failing, but when it tries to use the properties of the Google Service Class's it always says that I am not authenticated.
If you can help me I am very welcome.
i have a Problem with the Spreadsheed api and the "scopes".
With these script i want to update Cells on a Sheet.
I do not work with composer ich have just download the package in intereating it. The Token is already there and the error is from these row:
"$response = $service->spreadsheets_values->get($spreadsheetId, $range);"
<?php
session_start();
require_once __DIR__.'/vendor/autoload.php';
$client = new Google_Client();
$client->setAuthConfig('oauth-credentials.json');
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
if (isset($_SESSION['access_token']) && $_SESSION['access_token'])
{
$client->setAccessToken($_SESSION['access_token']);
echo "<pre>";
$service = new Google_Service_Sheets($client);
$spreadsheetId = 'xxx';
$range = 'Tabellenblatt1!A2:E';
$response = $service->spreadsheets_values->get($spreadsheetId, $range);
$values = $response->getValues();
if (count($values) == 0) {
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 <br>", $row[0], $row[4]);
}
}
} else {
$redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/api/oauth2callback.php';
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
?>
These Code brings the following Error
Fatal error: Uncaught exception 'Google_Service_Exception' with message '{
"error": {
"code": 403,
"message": "Request had insufficient authentication scopes.",
"errors": [
{
"message": "Request had insufficient authentication scopes.",
"domain": "global",
"reason": "forbidden"
}
],
"status": "PERMISSION_DENIED"
}
}
You have this scope defined:
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
For accessing a spreadsheet value:
$response = $service->spreadsheets_values->get($spreadsheetId, $range);
You should have:
$client->addScope(Google_Service_Sheets::SPREADSHEETS_READONLY);
or
$client->addScope(Google_Service_Sheets::SPREADSHEETS);
Source:
https://developers.google.com/identity/protocols/googlescopes#sheetsv4
You Must Update the scope as #random425 said,
but after that delete the Token.json.
that will start the process of verification again what will give you new token with new scope that you have changed to.
I'm using the Google PHP API. The documentation is rather lackluster... I want to allow users to connect their Google+ information and also use it to sign the users up in my database. In order to do that I need to get the email they use for their google account. I can't seem to figure out how to. It's easy enough in Facebook by forcing the permission when the users connect to my app. Anyone have any idea? This is the code I'm using to grab the users google+ profile and it works fine, except users may not have their email listed there.
include_once("$DOCUMENT_ROOT/../qwiku_src/php/google/initialize.php");
$plus = new apiPlusService($client);
if (isset($_GET['code'])) {
$client->authenticate();
$_SESSION['token'] = $client->getAccessToken();
header('Location: http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF']);
}
if (isset($_SESSION['token'])) {
$client->setAccessToken($_SESSION['token']);
}
if ($client->getAccessToken()) {
$me = $plus->people->get('me');
print "Your Profile: <pre>" . print_r($me, true) . "</pre>";
// The access token may have been updated lazily.
$_SESSION['token'] = $client->getAccessToken();
} else {
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
Without the users email address, it sort of defeats the purpose of allowing users to signup with Google+ Anyone more familiar with the Google API know how I can get it?
The UserInfo API is now supported by the Google API PHP Client.
Here's a small sample application:
http://code.google.com/p/google-api-php-client/source/browse/trunk/examples/userinfo/index.php
The important bit of the sample is here:
$client = new apiClient();
$client->setApplicationName(APP_NAME);
$client->setClientId(CLIENT_ID);
$client->setClientSecret(CLIENT_SECRET);
$client->setRedirectUri(REDIRECT_URI);
$client->setDeveloperKey(DEVELOPER_KEY);
$client->setScopes(array('https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/plus.me')); // Important!
$oauth2 = new apiOauth2Service($client);
// Authenticate the user, $_GET['code'] is used internally:
$client->authenticate();
// Will get id (number), email (string) and verified_email (boolean):
$user = $oauth2->userinfo->get();
$email = filter_var($user['email'], FILTER_SANITIZE_EMAIL);
print $email;
I'm assuming this snippet was called with a GET request including the authorization code. Remember to include or require apiOauth2Service.php in order for this to work. In my case is something like this:
require_once 'google-api-php-client/apiClient.php';
require_once 'google-api-php-client/contrib/apiOauth2Service.php';
Good luck.
Updated with today's API:
$googlePlus = new Google_Service_Plus($client);
$userProfile = $googlePlus->people->get('me');
$emails = $userProfile->getEmails();
This assumes the following:
You've authenticated the current user with the proper scopes.
You've set up $client with your client_id and client_secret.
Forgive me if I'm missing something, but how do you know what Google account to link them with if you don't have their email address? Usually, you'd prompt the user to enter their Google Account's email in order to find their profile in the first place.
Using OAuth2, you can request permissions through the scope parameter. (Documentation.) I imagine the scopes you want are https://www.googleapis.com/auth/userinfo.email and https://www.googleapis.com/auth/userinfo.profile.
Then, it's a simple matter to get the profile info once you've obtained your access token. (I assume you've been able to redeem the returned authorization code for an access token?) Just make a get request to https://www.googleapis.com/oauth2/v1/userinfo?access_token={accessToken}, which returns a JSON array of profile data, including email:
{
"id": "00000000000000",
"email": "fred.example#gmail.com",
"verified_email": true,
"name": "Fred Example",
"given_name": "Fred",
"family_name": "Example",
"picture": "https://lh5.googleusercontent.com/-2Sv-4bBMLLA/AAAAAAAAAAI/AAAAAAAAABo/bEG4kI2mG0I/photo.jpg",
"gender": "male",
"locale": "en-US"
}
There's got to be a method in the PHP library to make that request, but I can't find it. No guarantees, but try this:
$url = "https://www.googleapis.com/oauth2/v1/userinfo";
$request = apiClient::$io->makeRequest($client->sign(new apiHttpRequest($url, 'GET')));
if ((int)$request->getResponseHttpCode() == 200) {
$response = $request->getResponseBody();
$decodedResponse = json_decode($response, true);
//process user info
} else {
$response = $request->getResponseBody();
$decodedResponse = json_decode($response, true);
if ($decodedResponse != $response && $decodedResponse != null && $decodedResponse['error']) {
$response = $decodedResponse['error'];
}
}
}
Anyway, in the code you posted, just pass the desired scope to createAuthUrl():
else {
$authUrl = $client->createAuthUrl("https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/userinfo.profile");
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}