oauth2 access token expire - php

<?php
session_start();
require_once realpath(dirname(__FILE__) . '/Google/src/Google/autoload.php');
/************************************************
ATTENTION: Fill in these values! Make sure
the redirect URI is to this page, e.g:
http://localhost:8080/user-example.php
************************************************/
$client_id = 'xxxxx-1l76cd2vi4ik5oqm5s20nj965riu4hum.apps.googleusercontent.com';
$client_secret = 'secret';
$redirect_uri = 'http://www.audit.polydevs.co.uk/oauth2callback.php?login';
$client = new Google_Client();
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->setScopes('email');
/************************************************
If we're logging out we just need to clear our
local access token in this case
************************************************/
if (isset($_REQUEST['logout'])) {
unset($_SESSION['access_token']);
header("Location: login.php");
}
if (isset($_REQUEST['logoutInvalid'])) {
unset($_SESSION['access_token']);
header("Location: login.php?invalid");
}
/************************************************
If we have a code back from the OAuth 2.0 flow,
we need to exchange that with the authenticate()
function. We store the resultant access token
bundle in the session, and redirect to ourself.
************************************************/
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
/************************************************
If we have an access token, we can make
requests, else we generate an authentication URL.
************************************************/
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$client->setAccessToken($_SESSION['access_token']);
} else {
$authUrl = $client->createAuthUrl();
}
/************************************************
If we're signed in we can go ahead and retrieve
the ID token, which is part of the bundle of
data that is exchange in the authenticate step
- we only need to do a network call if we have
to retrieve the Google certificate to verify it,
and that can be cached.
************************************************/
if ($client->getAccessToken()) {
$_SESSION['access_token'] = $client->getAccessToken();
$token_data = $client->verifyIdToken()->getAttributes();
}
if($client->isAccessTokenExpired()) {
echo 'Access Token Expired'; // Debug
$client->authenticate;
$newAccessToken = json_decode($client->getAccessToken());
$client->refreshToken($newAccessToken->refresh_token);
}
if (strpos($client_id, "googleusercontent") == false) {
echo missingClientSecretsWarning();
exit;
}
if (isset($_REQUEST['login'])) {
if (isset($authUrl)) {
header('Location:'.$authUrl);
} else {
require_once('func/connect.php');
$query = "SELECT * FROM users WHERE email = ?";
$stmt = $db->prepare($query);
$stmt->bindValue(1, $token_data['payload']['email']);
$stmt->execute();
$count = $stmt->rowCount();
if ($count > 0) {
header('Location: index.php');
} else {
$plus = new Google_Service_Plus( $client );
$me = $plus->people->get('me');
$query = "INSERT INTO users (name,email,role) VALUES(?,?,?)";
$stmt = $db->prepare($query);
$stmt->bindValue(1, $me['displayName']);
$stmt->bindValue(2, $token_data['payload']['email']);
$stmt->bindValue(3, 'regular');
$stmt->execute();
header('Location: index.php');
}
}
}
Specifically here
if($client->isAccessTokenExpired()) {
echo 'Access Token Expired'; // Debug
$client->authenticate;
$newAccessToken = json_decode($client->getAccessToken());
$client->refreshToken($newAccessToken->refresh_token);
}
Once my token expires, I cannot logout nor access any of the webpages as they require to have a valid token..
nor can i login, as that requires it too!
Or alternatively, can I just disable it!
EDIT
I'm very sorry, I'm tired and assuming everyone knows what I'm talking about.. The issue is that when the access token expires, I can either unset the $_SESSION['access_token'] and force relogging in ( major problem ) or have a way of just refreshing / disabling the token/expire so it won't impede on any ongoing processes for the user.

I would recommend reading a basic guide about OAuth so you can get the general idea.
Basically the server and the client go through a series of steps to prove that they are who they say they are. Once this has been completed the server will issue a short lived access_token and a refresh_token.
You can then use this access_token in all Api requests. However this access_token has a limited lifetime. When it expires you must give the refresh_token to the server and it will issue another access_token
To do this with the Google Api PHP library you use this code
//$client is the GApi Client
if($client->isAccessTokenExpired()) {
echo 'Access Token Expired'; // Debug
$client->refreshToken('your_refresh_token');
}

Related

Fatal error: Uncaught exception 'Google\Service\Exception' with message '{ "error": "unauthorized_client", "error_description": "Unauthorized" }

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?

How can i navigate to same page after successful google/facebook login?

I have create a website using php which is having google and facebook login. This website having 6 pages. For all the 6 pages header and footer are common(included). Assume I am login into the site using google from page 5. After successful/failure login, the page navigate to index.php (page 1) instead of page5. How can i navigate to the same page after successful/failure login of google and facebook. Is this possible without adding all the pages in google/facebook developer console?
Also i have tried to change the header location after successful login. It throws cannot reach, out of time error. Can any one help to solve this problem. Thanks in advance.
Note: I am using google and facebook Oauth service for login.
Here is my code:
google login.
<?php
session_start();
require_once 'dbconnection.php';
//Google API PHP Library includes
require_once 'gvendor/vendor/autoload.php';
require_once 'gvendor/vendor/google/apiclient/src/Google/Client.php';
require_once 'gvendor/vendor/google/apiclient/src/Google/Service/Oauth2.php';
// Fill CLIENT ID, CLIENT SECRET ID, REDIRECT URI from Google Developer Console
$client_id = 'xxxxxxx';
$client_secret = 'xxxxxxx';
$redirect_uri = 'http://localhost:80/tthtml/index.php';
$simple_api_key = 'xxxxxxx';
global $googleauthUrl;
//Create Client Request to access Google API
$client = new Google_Client();
$client->setApplicationName("PHP Google OAuth Login Example");
$client->setClientId($client_id);
$client->setClientSecret($client_secret);
$client->setRedirectUri($redirect_uri);
$client->setDeveloperKey($simple_api_key);
$client->addScope("https://www.googleapis.com/auth/userinfo.email");
$client->setAccessType('offline');
//Send Client Request
$objOAuthService = new Google_Service_Oauth2($client);
try{
//Logout
if (isset($_REQUEST['logout'])) {
$client->revokeToken($_SESSION['access_token']);
unset($_SESSION['access_token']);
unset($_SESSION['google_user_name']);
session_unset();
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL)); //redirect user back to page
}
//Authenticate code from Google OAuth Flow
//Add Access Token to Session
if (isset($_GET['code'])) {
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL));
}
//Set Access Token to make Request
if (isset($_SESSION['access_token']) && $_SESSION['access_token']) {
$client->setAccessToken($_SESSION['access_token']);
}
//Get User Data from Google Plus
//If New, Insert to Database
if ($client->getAccessToken()) {
$userData = $objOAuthService->userinfo->get();
$_SESSION['google_user_name']=$userData['given_name'];
$_SESSION['user_id']=$userData->id;
if(!empty($userData)) {
$dbObj=new database();
$dbObj->openconnection();
$sql='select * from tttbl_user where google_fb_id='.$userData->id;
$existing_member = $dbObj->existingMember($sql);
if(empty($existing_member)) {
$sql="insert into tttbl_user (google_fb_id, user_name, gender, email_id, gplus_link, profile_photo, created_date) values('".$userData->id."','".$userData->name."','".$userData->gender."','".$userData->email."','".$userData->link."','".$userData->picture."',now())";
$dbObj->newUser($sql);
}
$dbObj->closeconnection();
}
}
else{
$googleauthUrl = $client->createAuthUrl();
}
}
catch(Exception $ee)
{ }
?>
facebook login
<?php //
//ob_start();
session_start();
require_once 'dbconnection.php';
require_once 'fvendor/vendor/autoload.php';
require_once 'fvendor/vendor/facebook/php-sdk/src/facebook.php';
// Create our Application instance (replace this with your appId and secret).
global $facebook_loginUrl;
$appId='xxxxxx';
$secretkey='xxxxxx';
$facebook = new Facebook(array(
'appId' => 'xxxxxxx',
'secret' => 'xxxxxxxx',
));
// Get User ID
$fb_user = $facebook->getUser();
if(isset($_REQUEST['fb_logout'])){
//$accessToken=null;
//$logoutUrl = $helper->getLogoutUrl($_SESSION['facebook_access_token'], 'http://localhost/fblogin/fblogin.php');
//unset($_SESSION['facebook_access_token']);
unset($_SESSION['facebook_user_name']);
session_unset();
session_destroy();
$fb_user = null;
header('Location: http://localhost:80/tthtml/index.php');
}
if ($fb_user) {
try {
// Proceed knowing you have a logged in user who's authenticated.
$uid = $facebook->getUser();
$user_profile = $facebook->api('/me?fields=id,name,picture,email,gender');
}
catch (FacebookApiException $e) {
error_log($e);
$fb_user = null;
}
}
else
{
$facebook_loginUrl = $facebook->getLoginUrl(array('scope' => 'email,user_birthday,user_photos','req_perms' => 'user_mobile_phone',));
$facebookurlstring=$facebook_loginUrl;
$x=strpos($facebookurlstring,'redirect_uri=');
$y=strpos($facebookurlstring, 'state');
$facebookurllength= strlen($facebookurlstring);
//substr($str,0,$y+13).'http://localhost/tthtml/index.php'.substr($str, $y+13+$x,$length)
$facebook_loginUrl=substr($facebookurlstring,0,$x+13).'http://localhost/tthtml/index.php'.substr($facebookurlstring, $y-1,$facebookurllength);
}
if($fb_user)
{
$userid=$user_profile['id'];
$username = $user_profile['name'];
$useremail = $user_profile['email'];
$userpicture=$user_profile['picture']['data']['url'];
$usergender=$user_profile['gender'];
$mobilenumber=$user_profile['user_mobile_phone'];
$_SESSION['facebook_user_name']=$username;
$_SESSION['user_id']=$userid;
if(isset($_SESSION['facebook_user_name'])&& $_SESSION['facebook_user_name']) {
$dbObj=new database();
$dbObj->openconnection();
$sql='select * from tttbl_user where google_fb_id='.$userid.';';
$existing_member = $dbObj->existingMember($sql);
if(empty($existing_member)) {
$sql="insert into tttbl_user (google_fb_id, user_name, gender, email_id, profile_photo, created_date)"
. " values('".$userid."','".$username."','".$usergender."','".$useremail."','".$userpicture."',now())";
$dbObj->newUser($sql);
}
$dbObj->closeconnection();
}
}
?>
If I change the redirect URI, it will search in the URL list in developer console. If it is not available in the list of developer console, then it throws ulr is not available in whitelist(for facebook) and page not found (for google) error is thrown.
Try to redirect with jQuery code
echo "<script>window.location.href ='yourpage.php';</script>";

How to get this session working in Google login php?

I am logging a user using Google login. I have included all the necessary files needed for Google login. I have created a PHP script for log-in. I have all my authentication and redirection info in place. However, I do not understand why am I not getting email field which I am getting from googleClient in my session. Please help.
Here is my code:
<?php
$google_client_id = '#########.apps.googleusercontent.com';
$google_client_secret = 'xxxxxxxxxxxxxxxxxxx';
$google_redirect_url = 'http://localhost/project/profile.php';
$google_developer_key = '';
//include google api files
require_once '../src/Google_Client.php';
require_once '../src/contrib/Google_Oauth2Service.php';
session_start();
$gClient = new Google_Client();
$gClient->setClientId($google_client_id);
$gClient->setClientSecret($google_client_secret);
$gClient->setRedirectUri($google_redirect_url);
$google_oauthV2 = new Google_Oauth2Service($gClient);
if (isset($_REQUEST['reset']))
{
unset($_SESSION['token']);
$gClient->revokeToken();
header('Location: ' . filter_var($google_redirect_url, FILTER_SANITIZE_URL));
}
if (isset($_GET['code']))
{
$gClient->authenticate($_GET['code']);
$_SESSION['token'] = $gClient->getAccessToken();
header('Location: ' . filter_var($google_redirect_url, FILTER_SANITIZE_URL));
return;
}
if (isset($_SESSION['token']))
{
$gClient->setAccessToken($_SESSION['token']);
}
if ($gClient->getAccessToken())
{
//Get user details if user is logged in
$user = $google_oauthV2->userinfo->get();
$user_id = $user['id'];
$user_name = filter_var($user['name'], FILTER_SANITIZE_SPECIAL_CHARS);
$email = filter_var($user['email'], FILTER_SANITIZE_EMAIL);
$profile_url = filter_var($user['link'], FILTER_VALIDATE_URL);
$profile_image_url = filter_var($user['picture'], FILTER_VALIDATE_URL);
$personMarkup = "$email<div><img src='$profile_image_url?sz=50'></div>";
$_SESSION['token'] = $gClient->getAccessToken();
$_SESSION['email'] = $email;
}
else
{
//get google login url
$authUrl = $gClient->createAuthUrl();
}
?>
My profile.php looks like this -
It results in -
Notice: Undefined index: email on line 4
After this script runs, the control jumps to the next page where it says that email is not found in session. Should I create a new Google_Client()? Whats the proper way to do this series of interaction after login?
First of all it will work on localhost, no problem. Because I have just created google and facebook login and it works fine.
you need to add Google ClientID and Client secret key from the console developer google where you have created web app and ouath key.
In main Login page you can redirect to another page...
/*! \brief Configure the client object
* Exchange authorization code for refresh and access tokens
*/
if (isset($_GET['code'])) {
$gClient->authenticate($_GET['code']);
$_SESSION['token'] = $gClient->getAccessToken(); /**< retrieve the access token with the getAccessToken method */
header('Location: ' . filter_var($redirectURL, FILTER_SANITIZE_URL)); /**< Redirect the user to $auth_url: */
}
if (isset($_SESSION['token'])) {
$gClient->setAccessToken($_SESSION['token']); /**< apply an access token to a new Google_Client object */
}
$authUrl = $gClient->createAuthUrl(); /**< Generate a URL to request access from Google's OAuth 2.0 server */
Try this..
!(set($_GET['code'])) {
$gClient->authenticate($_GET['code']);
$_SESSION['token'] = $gClient->getAccessToken(); /**< retrieve the access token with the getAccessToken method */
header('Location: ' . filter_var($redirectURL, FILTER_SANITIZE_URL)); /**< Redirect the user to $auth_url: */ }
if (isset($_SESSION['token'])) {
$gClient->setAccessToken($_SESSION['token']); /**< apply an access token to a new Google_Client object */
})

Get post from Google+ without browser's authentication in google's account via PHP

I'm want to get google+ posts via PHP, but google requires my login via browser.
It's possible provide the account's authentication via PHP, allowing me to get the posts without login every time I want to get the posts?
The code is:
<?php
require_once 'src/Google_Client.php';
require_once 'src/contrib/Google_PlusService.php';
session_start();
$client = new Google_Client();
$client->setApplicationName("Google+ PHP Starter Application");
// Visit https://code.google.com/apis/console?api=plus to generate your
// client id, client secret, and to register your redirect uri.
$client->setClientId('clientid');
$client->setClientSecret('clientsecret');
$client->setRedirectUri('http://localhost/OLA/google+/simple.php/b.html');
$client->setDeveloperKey('apikey');
$plus = new Google_PlusService($client);
if (isset($_GET['logout'])) {
unset($_SESSION['token']);
}
if (isset($_GET['code'])) { // login stuff <-------
if (strval($_SESSION['state']) !== strval($_GET['state'])) {
die("The session state did not match.");
}
$client->authenticate();
$_SESSION['token'] = $client->getAccessToken();
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
header('Location: ' . filter_var($redirect, FILTER_SANITIZE_URL));
}
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>";
$params = array('maxResults' => 100);
$activities = $plus->activities->listActivities('me', 'public', $params);
//print "Your Activities: <pre>" . print_r($activities, true) . "</pre>";
$params = array(
'orderBy' => 'recent',
'maxResults' => '20'//20
);
$q = "tag";
$results = $plus->activities->search($q, $params);
//code ....
// The access token may have been updated lazily.
$_SESSION['token'] = $client->getAccessToken();
} else {
// This is the part that logs me in via browser <------
$state = mt_rand();
$client->setState($state);
$_SESSION['state'] = $state;
$authUrl = $client->createAuthUrl();
print "<a class='login' href='$authUrl'>Connect Me!</a>";
}
?>
Yep, just call as you would and use the simple API access key - you can retrieve public information, but you will have to supply to long numeric ID for the user you're retrieving posts for rather than using the string 'me'. Take a look at the latest version of the library as well: https://github.com/google/google-api-php-client as well. You need to setup your client as you were doing, with an API key from a project which has the Google+ enabled on https://developers.google.com/console
$client = new Google_Client();
$client->setApplicationName("Post Fetcher");
$client->setDeveloperKey('PUT_YOUR_API_KEY_HERE_OR_IT_WONT_WORK');
$plus = new Google_Service_Plus($client);
$activities = $this->plus->activities
->listActivities("118051310819094153327", "public");

Google oauth2 get userdetails not working and hanging php

I copied this from the test folder included in the php sdk. It redirects to google for authentication as expected but when calling $oauth2->userinfo->get() it just hangs there. The cloud console said the error was 400 but I don't see what I could be doing wrong.
I updated the setting as per what is on my page. I've been searching for an answer for 2 hours. Please help :(
/* OAuth settings */
$clientID = 'blahblah.apps.googleusercontent.com';
$clientSecret = 'secret';
$redirect = 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
$developerKey = 'key';
$client = new Google_Client();
$client->setApplicationName("Study-Corner");
$client->setClientId($clientID);
$client->setClientSecret($clientSecret);
$client->setRedirectUri($redirect);
$client->setDeveloperKey($developerKey);
$oauth2 = new Google_Oauth2Service($client);
if(isset($_GET['code'])) {
$client->authenticate($_GET['code']);
// get the access token
$_SESSION['token'] = $client->getAccessToken();
// redirect back
header('Location: '. filter_var($redirect, FILTER_SANITIZE_URL));
return;
}
if(isset($_SESSION['token'])) {
// set the access token
$client->setAccessToken($_SESSION['token']);
}
/* check if we have access */
if($client->getAccessToken()) {
$user = $oauth2->userinfo->get();
// These fields are currently filtered through the PHP sanitize filters.
// See http://www.php.net/manual/en/filter.filters.sanitize.php
$email = filter_var($user['email'], FILTER_SANITIZE_EMAIL);
$img = filter_var($user['picture'], FILTER_VALIDATE_URL);
print $email;
// The access token may have been updated lazily.
$_SESSION['token'] = $client->getAccessToken();
} else {
$authUrl = $client->createAuthUrl();
header("Location: ".$authUrl);
die;
}
Add $client->setScopes('profile); to your client details.

Categories