I am implementing an Audio library manager which uses user's google drive as backend storage. I am using PHP (google-api-php-client-2.2.1) to get the user's authorization for accessing his/her google drive.
So far I am able to receive access token and refresh token using example code from google (https://developers.google.com/api-client-library/php/auth/web-app), and also tested by listing files of user's google drive.
However, I am not able to figure out programmatically which user has given authorization to my application. Just user's email address will do. I don't need any other information.
I am using the following code.
<?php
require_once 'google-api-php-client/vendor/autoload.php';
session_start();
$client = new Google_Client();
$client->setAuthConfig('client_secret.json'); //downloaded from google oauth credentials portal. It includes redirect URL
$client->setAccessType("offline"); // offline access
$client->setIncludeGrantedScopes(true); // incremental auth
$client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY);
if (! isset($_GET['code'])) {
//Get authorization and User consent from Google
$auth_url = $client->createAuthUrl();
header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
} else { //Authorization completed
//Get access token
$client->authenticate($_GET['code']);
$_SESSION['access_token'] = $client->getAccessToken();
$_SESSION['refresh_token'] = $client->getRefreshToken();
echo "Access Token<br>";
var_dump ($_SESSION['access_token']); //works
echo "<br>";
echo "Refresh Token<br>";
var_dump ($_SESSION['refresh_token']); //works
echo "<br>";
$service=new Google_Service_Oauth2($client);
echo "Auth2 Service created<br>"; //Getting this print
$usr_info=$service->userinfo;
echo "User Info<br>"; //Getting this print
var_dump ($usr_info); //Getting this print, Very long JSON structure. But info is mostly pertaining to my app...no user information showing here
echo "<br>";
//$usr_info_get = $usr_info->get(); //Throwing Error
//$usr_info_get = $usr_info->get(['email']); //Throwing Error
//$usr_info_get = $usr_info->get()['email']; //Throwing Error
echo "User Info Get<br>";
//var_dump ($usr_info_get);
echo "<br>";
}
?>
The class for userInfo is like this
class Google_Service_Oauth2_Resource_Userinfo extends Google_Service_Resource
{
/**
* (userinfo.get)
*
* #param array $optParams Optional parameters.
* #return Google_Service_Oauth2_Userinfoplus
*/
public function get($optParams = array())
{
$params = array();
$params = array_merge($params, $optParams);
return $this->call('get', array($params), "Google_Service_Oauth2_Userinfoplus");
}
}
The params for get() method should be optional, but
$userInfo->get()
also given me Server Error.
I am not finding anything else from my google search on this.
I tried this (6 year old thread) but code errors out (apiHttpRequest class not found)
How to identify a Google OAuth2 user?
I tried reading about openID but seems kinda complex. Also, not sure if google-api-php-client has helper class for openID.
I would really appreciate your help. Already spent 2+ days reading google api client php code but now up against the wall.
Related
Hi I an issue trying to implement the google plus Api for non google plus accounts. I followed the code samples from the google developer site. In trying to authenticate a user i noticed that if you cancel/deny the creation of a google plus profile it gives a blank screen with a url "https://plus.google.com/up?continue=". If i reload the page i am giving the create google plus profile dialog , and upon cancelling again presented with a blank screen. I want to be able to let user's cancel and be returned to my site.
<?php
require_once ('includes/utilities.inc.php');
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_PlusService.php';
$client = new Google_Client();
$client->setApplicationName("Google Plus PHP Starter Application");
// Visit https://code.google.com/apis/console?api=plus to generate your
// oauth2_client_id, oauth2_client_secret, and to register your oauth2_redirect_uri.
$client->setClientId('******************');
$client->setClientSecret('****************');
$client->setRedirectUri("***********************");
$client->setDeveloperKey('***********************');
$plus = new Google_PlusService($client);
if (isset($_GET['code'])) {
$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()) {
$activities = $plus->activities->listActivities('me', 'public');
print 'Your Activities: <pre>' . print_r($activities, true) . '</pre>';
// We're not done yet. Remember to update the cached access token.
// Remember to replace $_SESSION with a real database or memcached.
$_SESSION['token'] = $client->getAccessToken();
} else {
$authUrl = $client->createAuthUrl();
print "<a href='$authUrl'>Connect Me!</a>";
}
echo "<pre>";
print_r($user_google);
print_r( $_SESSION['token']);
echo"</pre>";
?>
I am trying to authentify a domain for google docs scope. This is the url:
https://www.google.com/accounts/AuthSubRequest?next=http%3A%2F%2Fwww.mydomain.edu.au%2Fcomponents%2Fgoogle%2FretrieveToken.php&scope=https%3A%2F%2Fdocs.google.com%2Ffeeds%2F&session=1&secure=0&hd=default
So my domain is: www.mydomain.edu.au
But when makng the request Then i get this answer:
The page you have requested cannot be displayed. Another site was requesting access to your Google Account, but sent a malformed request. Please contact the site that you were trying to use when you received this message to inform them of the error. A detailed error message follows:
The site "http://edu.au" has not been registered.
So its identified as edu.au domain.
Is there a way around this?
Thanx
sample code for uploading document to google docs:
public static function uploadDocs($data = array())
{
if (!self::checkInput($data)) return false;
$data['url'] = Google::docsAPIUrl.'default/private/full'.self::getFolder($data['folderId']);
//"?convert=false"
$headers = Google::getAuthToken();
array_push($headers, Google::getGData());
$contentHeaders = self::getInputHeaders($data);
array_push($headers, 'Content-Length: '.$contentHeaders['length']);
array_push($headers, 'Content-Type: '.$contentHeaders['type']);
array_push($headers, 'Slug: '.Html::win2utf8($data['docTitle']));
if ($data['inputMethod'] == 'File')
{
$data['input'] = ((fread(fopen($data['input'], 'rb'), filesize($data['input']))));
}
$curl = Google::curl($data['url'], null, $data['input'], $headers);
if (Curl::checkCode($curl['code']))
{
return self::parseNewXML($curl['response']);
}
else
{
Google::$error = array('errorCode'=>$curl['code'],'errorString'=>$curl['response']);
return false;
}
}
AuthSub is deprecated. You should be using OAuth 2.0 and Drive API v2.
I have set up magento locally in my system using XAMPP
I have created a file in root directory named dm.php with the contents
<?php
/**
* Example of products list retrieve using Customer account via Magento REST API. OAuth authorization is used
*/
$callbackUrl = "http://localhost/dm.php";
$temporaryCredentialsRequestUrl = "http://localhost/mage2/oauth/initiate?oauth_callback=" . urlencode($callbackUrl);
$adminAuthorizationUrl = 'http://localhost/mage2/oauth/authorize';
$accessTokenRequestUrl = 'http://localhost/mage2/oauth/token';
$apiUrl = 'http://localhost/mage2/api/rest';
$consumerKey = 'enhksf7u33p3snubewb6zcq0z9c63bvv';
$consumerSecret = 'p7e835cdcxofokeep749jgzz4l1e306p';
session_start();
if (!isset($_GET['oauth_token']) && isset($_SESSION['state']) && $_SESSION['state'] == 1) {
$_SESSION['state'] = 0;
}
try {
$authType = ($_SESSION['state'] == 2) ? OAUTH_AUTH_TYPE_AUTHORIZATION : OAUTH_AUTH_TYPE_URI;
$oauthClient = new OAuth($consumerKey, $consumerSecret, OAUTH_SIG_METHOD_HMACSHA1, $authType);
$oauthClient->enableDebug();
if (!isset($_GET['oauth_token']) && !$_SESSION['state']) {
$requestToken = $oauthClient->getRequestToken($temporaryCredentialsRequestUrl);
$_SESSION['secret'] = $requestToken['oauth_token_secret'];
$_SESSION['state'] = 1;
header('Location: ' . $adminAuthorizationUrl . '?oauth_token=' . $requestToken['oauth_token']);
exit;
} else if ($_SESSION['state'] == 1) {
$oauthClient->setToken($_GET['oauth_token'], $_SESSION['secret']);
$accessToken = $oauthClient->getAccessToken($accessTokenRequestUrl);
$_SESSION['state'] = 2;
$_SESSION['token'] = $accessToken['oauth_token'];
$_SESSION['secret'] = $accessToken['oauth_token_secret'];
header('Location: ' . $callbackUrl);
exit;
} else {
$oauthClient->setToken($_SESSION['token'], $_SESSION['secret']);
$resourceUrl = "$apiUrl/products";
$oauthClient->fetch($resourceUrl);
$productsList = json_decode($oauthClient->getLastResponse());
print_r($productsList);
}
} catch (OAuthException $e) {
print_r($e);
}
But this is giving me the following error
Fatal error: Class 'OAuth' not found in D:\Webserver\xampp\htdocs\dm.php on line 19
Can anybody shed some light on this
Thanks
Since oauth is not possible to install in xampp windows i changed the contents of my dm.php file to this.
<?php
$ch = curl_init('http://localhost/mage2/api/rest/customers');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$customers = curl_exec($ch);
echo $customers;
?>
Now i am getting an error like this
{"messages":{"error":[{"code":403,"message":"Access denied"}]}}
What am i doing wrong?
First of all
Go to magento admin panel System->Webservice->RESt Roles->Guest->Resources Access ->SET ALL
Similarly Go to System->Webservice->RESt Attribute->Guest->Resources Access ->SET ALL
Then Hit this url http://****/chanchal/magento/api/rest/products in web Browser and check what error it shows....
According to me it must show product in your website in xml format.
Please let me know..
EDIT:
I configured a localhost just now and got this output refer the Screenshot. Be sure there is product in your magento.
Similarly follow the above steps for admin,customer then create a Ouath consumer from admin panel , Install RESTClient For Mozilla Firefox And follow Here
These for steps are necessary for the setup..the link might help you..
Authentication Endpoints
1./oauth/initiate - this endpoint is used for retrieving the Request Token.
2./oauth/authorize - this endpoint is used for user authorization (Customer).
3./admin/oauth_authorize - this endpoint is used for user authorization (Admin).
4./oauth/token - this endpoint is used for retrieving the Access Token.
Let me know if you have any issues.
Best of luck
A bit of code modifications will easily solve this error 403 forbidden.
What magento engine does is that it uses the default guest user to provide access to the REST api methods. The guest user does not have much powers so it should be better to change this functionality of magento. There are 2 ways of doing this:
1) Quick and dirty fix: in the file /app/code/core/Mage/Api2/Model/Auth.php, change the value of: DEFAULT_USER_TYPE = 'guest' to DEFAULT_USER_TYPE = 'admin'. In the file /app/code/core/Mage/Api2/Model/Auth/Adapter.php, change this line from return (object) array('type' => Mage_Api2_Model_Auth::DEFAULT_USER_TYPE, 'id' => null); to this:
return (object) array('type' => Mage_Api2_Model_Auth::DEFAULT_USER_TYPE, 'id' => '1');
This way the authentication system will not be broken.
2) Proper and long run fix: Override the two functionalities using the magento overriding mechanism to have a better solution in accordance to magento standards. This way the core files will be intact.
We use this link to install oauth for php. Its good and easy to add extension for php.
install oauth php
I hope it helps to all and would solved 'OAuth' not found fatal error.
I had the same issue and was struggling for a week but just try insatlling new version of xammp or wamp with supports ouath.The better solution was ,I installed Ammps 1.9 and in php5.4 I resolved the extension of oauth but still make sure that you select the proper php for extension oauth is supported (php5.4)
For installing Oauth : http://www.magentocommerce.com/api/rest/authentication/oauth_authentication.html
Installing PHP Extension for Oauth :
1. Download php_oauth.dll file and add it under C:\xampp\php\ext\
2. add [PHP_OAUTH] extension=php_oauth.dll in php.ini
i'm using the examples provided in the "google-api-php-client"-Library (http://code.google.com/p/google-api-php-client/) to implement user login and authorization on my website with google services.
I didn't make any changes to the examples, except adding my Client-ID, etc..
The authorization itself works fine: Users can login and i can fetch the provided informations.
However, when leaving the page, the whole authorization procedure is called again; users are not remembered and need to grant permissions again, which is some kind of annoying and not typical for google-logins as i know them.
For example: On stackoverflow, i'm logged in with my google account.
Whenever i revisit this site, i'm logged in automaticly, or (if logged out) just have to log in again - i do not have to confirm the general rights again.
Using the examples on my site however, forces the user to allow access whenever the site is visited again.
Did i make any mistakes, when using the examples?
What do i have to do, to avoid the permission request over and over again?
Thanks in advance for any kind of help!
Use this code for first time to retrieve access_code and save it to database:
<?php
require 'google-api-php-client/src/Google_Client.php';
require 'google-api-php-client/src/contrib/Google_DriveService.php';
require 'google-api-php-client/src/contrib/Google_Oauth2Service.php';
session_start();
$client = new Google_Client();
$client->setClientId(CLIENT_ID);
$client->setClientSecret(CLIENT_SECRET);
$client->setRedirectUri(REDIRECT_URI);
$client->setScopes(array(
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile'));
$client->setUseObjects(true);
$service = new Google_DriveService($client);
$client->authenticate();
$_SESSION['token'] = $client->getAccessToken();
const ACCESS_TOKEN=$_SESSION['token'];
//code here to save in database
?>
Once ACCESS_TOKEN is saved in database change code to:
<?php
require 'google-api-php-client/src/Google_Client.php';
require 'google-api-php-client/src/contrib/Google_DriveService.php';
require 'google-api-php-client/src/contrib/Google_Oauth2Service.php';
session_start();
$client = new Google_Client();
$client->setClientId(CLIENT_ID);
$client->setClientSecret(CLIENT_SECRET);
$client->setRedirectUri(REDIRECT_URI);
$client->setScopes(array(
'https://www.googleapis.com/auth/drive',
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile'));
$client->setUseObjects(true);
$service = new Google_DriveService($client);
//ACCESS_TOKEN is already saved in database, is being saved on first time login.
$_SESSION['access_token'] = ACCESS_TOKEN;
if (isset($_SESSION['access_token'])) {
$client->setAccessToken($_SESSION['access_token']);
}
if ($client->getAccessToken())
{
$userinfo = $service->about->get();
echo '<script>console.log('.json_encode($userinfo).');</script>';
$userinfoService = new Google_OAuth2Service($client);
$user = $userinfoService->userinfo->get();
echo '<script>console.log('.json_encode($user).');</script>';
}
?>
That works fine for me.
Based on the kaushal's answer:
<?php
require_once 'globals.php';
require_once 'google-api-php-client/src/Google_Client.php';
require_once 'google-api-php-client/src/contrib/Google_DriveService.php';
$client = new Google_Client();
// Get your credentials from the APIs Console
$client->setClientId('YOUR_ID');
$client->setClientSecret('YOUR_SECRET');
$client->setRedirectUri('REDIRECT_URI');
$client->setScopes(array('https://www.googleapis.com/auth/drive'));
$service = new Google_DriveService($client);
$client->setUseObjects(true);
//if no token in the session
if ($_SESSION['google_token'] == '') {
//get stored token from DB
$sToken = $oDb->getOne("SELECT `google_token` FROM `users` WHERE `u_id` = " . (int)$_SESSION['user_id']);
//if no stored token in DB
if ($sToken == '') {
//autentificate user
$client->authenticate();
//get new token
$token = $client->getAccessToken();
//set token in session
$_SESSION['google_token'] = $token;
// set token in DB
$oDb->Query("UPDATE `users` SET `google_token`='$token' WHERE `u_id` = " . (int)$_SESSION['user_id']);
} else {
$_SESSION['google_token'] = $sToken;
}
}
$client->setAccessToken($_SESSION['google_token']);
//do what you wanna do with clients drive here
?>
The Google Drive SDK documentation includes a complete PHP sample application that you can use as a reference to get started:
https://developers.google.com/drive/examples/php
Basically, once the user is logged in and you retrieve access token and refresh token, you store those credentials in a database and reuse them instead of asking the user to authenticate every time.
I'm trying to find information on securing a HTTP REST API in a Symfony project, but all I can find is information about using sfGuardPlugin. From what I can see, this plugin isn't very useful for web services. It tries to have user profile models (which aren't always that simple) and have "sign in" and "sign out" pages, which obviously are pointless for a stateless REST API. It does a lot more than I'll ever have need for and I what to keep it simple.
I want to know where to implement my own authorisation method (loosely based on Amazon S3's approach). I know how I want the authorisation method to actually work, I just don't know where I can put code in my Symfony app so that it runs before every request is processed, and lets approved requests continue but unsuccessful requests return a 403.
Any ideas? I can't imagine this is hard, I just don't know where to start looking.
There is a plugin for RESTful authentication -> http://www.symfony-project.org/plugins/sfRestfulAuthenticationPlugin
Not used it though ....
How where you planning to authenticate users ?
The jobeet tutorial uses tokens ... http://www.symfony-project.org/jobeet/1_4/Doctrine/en/15
I ended up finding what I was looking for by digging into the code for sfHttpAuthPlugin. What I was looking for was a "Filter". Some details and an example is described in the Askeet sample project.
Stick a HTTP basicAuth script in your <appname>_dev.php (Symfony 1.4 =<) between the project configuration "require" and the configuration instance creation.
Test it on your dev. If it works, put the code in your index.php (the live equivalent of <appname>_dev.php) and push it live.
Quick and dirty but it works. You may want to protect that username/password in the script though.
e.g.
$realm = 'Restricted area';
//user => password
$users = array('username' => 'password');
if (empty($_SERVER['PHP_AUTH_DIGEST'])) {
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Digest realm="'.$realm.
'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');
die('Text to send if user hits Cancel button');
}
// || !isset($users[$data['username']]
// analyze the PHP_AUTH_DIGEST variable
if (!($data = http_digest_parse($_SERVER['PHP_AUTH_DIGEST'])) || !isset($users[$data['username']])) {
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Digest realm="'.$realm.
'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');
die('Wrong Credentials!');
}
// generate the valid response
$A1 = md5($data['username'] . ':' . $realm . ':' . $users[$data['username']]);
$A2 = md5($_SERVER['REQUEST_METHOD'].':'.$data['uri']);
$valid_response = md5($A1.':'.$data['nonce'].':'.$data['nc'].':'.$data['cnonce'].':'.$data['qop'].':'.$A2);
if ($data['response'] != $valid_response) {
header('HTTP/1.1 401 Unauthorized');
header('WWW-Authenticate: Digest realm="'.$realm.
'",qop="auth",nonce="'.uniqid().'",opaque="'.md5($realm).'"');
die('Wrong Credentials!');
}
// function to parse the http auth header
function http_digest_parse($txt)
{
// protect against missing data
$needed_parts = array('nonce'=>1, 'nc'=>1, 'cnonce'=>1, 'qop'=>1, 'username'=>1, 'uri'=>1, 'response'=>1);
$data = array();
$keys = implode('|', array_keys($needed_parts));
preg_match_all('#(' . $keys . ')=(?:([\'"])([^\2]+?)\2|([^\s,]+))#', $txt, $matches, PREG_SET_ORDER);
foreach ($matches as $m) {
$data[$m[1]] = $m[3] ? $m[3] : $m[4];
unset($needed_parts[$m[1]]);
}
return $needed_parts ? false : $data;
}
// ****************************************************************************
// ok, valid username & password.. continue...