how to send referer in php code for google client? - php

As mentioned the error here:
Error calling GET https://www.googleapis.com/plus/v1/people/me?key=MYKEY: (403) The request did not specify any referer. Please ensure that the client is sending referer or use the API Console to remove the referer restrictions
My code:
$client = new Google_Client();
$client->setApplicationName("maaa");
//$client->setHttpClient($httpClient);
echo "login 2";
// Visit https://code.google.com/apis/console?api=plus to generate your
// client id, client secret, and to register your redirect uri.
$client->setClientId(GOOGLE_CLIENT_ID);
$client->setClientSecret(GOOGLE_CLIENT_SECRET);
$client->setRedirectUri($callbackurl);
$client->setDeveloperKey(GOOGLE_API_KEY);
$client->setAccessType("online");
$client->setApprovalPrompt("auto");
$plus = new Google_PlusService($client);
echo "login 3";
if (isset($_GET['code'])) {
echo "login inside....";
try {
$client->authenticate();
} catch(Exception $e) {
echo $e;
}
$token = $client->getAccessToken();
try {
$userProfile = $plus->people->get("me");
} catch(Exception $e) {
//ERROR Error calling GET https://www.googleapis.com/plus/v1/people/me?key=mYKEY: (403) The request did not specify any referer. Please ensure that the client is sending referer or use the API Console to remove the referer restrictions
echo $e;
}
$id = $userProfile['id'];
return array(
'user' => $id,
'network' => 'google',
'userprofile' => $userProfile,
'token' => $token,
'loginUrl' => null,
'logoutUrl' => null
);
} else {
$authUrl = $client->createAuthUrl();
return array(
'user' => 0,
'network' => 'google',
'userprofile' => $userProfile,
'token' => null,
'loginUrl' => $authUrl,
'logoutUrl' => null
);
}
Following is the setting for my api. If I keep the below settings then everything works really well but If I wanted to keep the restriction on HTTP then it won't work. If anyone know to make it work without having any issue with the HTTP option then please let me know.
tHANKS and please let me know if anyone have any idea that how I can send the referer to google client.....

Related

Zoom API - Request to check email does not work

I am trying to consume Zoom's API using PHP and Oauth2. I was able to connect to the aplication and get the token using the generic lib oauth2-client. But, when I try to make a simple request, I get an error, saying that the email is missing. This is my code:
<?php
session_start();
require __DIR__ . '/vendor/autoload.php';
$provider = new \League\OAuth2\Client\Provider\GenericProvider([
'clientId' => 'meuclientid',
'clientSecret' => 'meuclientsecret',
'redirectUri' => 'http://localhost/teste_oauth2/',
'urlAuthorize' => 'https://zoom.us/oauth/authorize',
'urlAccessToken' => 'https://zoom.us/oauth/token',
'urlResourceOwnerDetails' => 'https://api.zoom.us/v2/users/me'
]);
// If we don't have an authorization code then get one
if (!isset($_GET['code'])) {
$authorizationUrl = $provider->getAuthorizationUrl();
// Get the state generated for you and store it to the session.
$_SESSION['oauth2state'] = $provider->getState();
// Redirect the user to the authorization URL.
header('Location: ' . $authorizationUrl);
exit;
// Check given state against previously stored one to mitigate CSRF attack
}
elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
unset($_SESSION['oauth2state']);
exit('Invalid state');
} else {
try {
// Try to get an access token using the authorization code grant.
$accessToken = $provider->getAccessToken('authorization_code', [
'code' => $_GET['code']
]);
$request = $provider->getAuthenticatedRequest(
'GET',
'https://api.zoom.us/v2/users/email',
$accessToken,
['email' => 'meuemail#gmail.com']
);
var_dump($provider->getResponse($request));
die('aqui');
} catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
// Failed to get the access token or user details.
echo $e->getMessage();
exit;
}
}
?>
As you can see, I am passing the email on the request. But I am getting the Fatal error: Uncaught GuzzleHttp\Exception\ClientException: Client error: GET https://api.zoom.us/v2/users/email resulted in a 400 Bad Request response: {"code":300,"message":"Email is required."}
Can anyone help me?
You are using
['email' => 'meuemail#gmail.com']
which is not allowed in the function $provider->getAuthenticatedRequest
You need to pass it with the existing URL:
$request = $provider->getAuthenticatedRequest(
'GET',
'https://api.zoom.us/v2/users/email?email=meuemail#gmail.com',
$accessToken
);
I hope this helps..!!
Zoom API Reference: https://marketplace.zoom.us/docs/api-reference/zoom-api/users/useremail
OAuth Reference: https://github.com/thephpleague/oauth2-client

troubleshooting getAccessToken for oauth2 fitbit login

I'm trying to use djchen's Fitbit wrapper for thephpleague code to get Fitbit OAuth2 access for my website. It can be found here: https://github.com/djchen/oauth2-fitbit
This was working perfectly for a while and now suddenly, I'm getting "Forbidden" error. I can't remember changing any code on the login.php file. Any ideas as to why this would happen?
Here is my main code:
<?php namespace djchen\OAuth2\Client\Provider;
require __DIR__.'/vendor/autoload.php';
require __DIR__.'/vendor/oauth2-fitbit-master/src/Provider/Fitbit.php';
require __DIR__.'/vendor/oauth2-fitbit-master/src/Provider/FitbitUser.php';
use djchen\Oauth2\Client\Provider\Fitbit;
use djchen\Oauth2\Client\Provider\FitbitUser;
$provider = new Fitbit([
'clientId' => '****',
'clientSecret' => '****',
'redirectUri' => '****'
]);
ob_start();
ini_set('session.save_path',realpath(dirname($_SERVER['DOCUMENT_ROOT']) . '/var/php_sessions'));
session_start();
// If we don't have an authorization code then get one
if (!isset($_GET['code'])) {
echo "going down this path \n";
// Fetch the authorization URL from the provider; this returns the
// urlAuthorize option and generates and applies any necessary parameters
// (e.g. state).
$authorizationUrl = $provider->getAuthorizationUrl();
// Get the state generated for you and store it to the session.
$_SESSION['oauth2state'] = $provider->getState();
// Redirect the user to the authorization URL.
header('Location: ' . $authorizationUrl);
exit;
// Check given state against previously stored one to mitigate CSRF attack
} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
echo $_SESSION['oauth2state'] . " is the oauth2state saved \n";
echo $_GET['state'] . " is the get_state \n";
unset($_SESSION['oauth2state']);
exit('Invalid state');
} else {
try {
// Try to get an access token using the authorization code grant.
$accessToken = $provider->getAccessToken('authorization_code', ['code' => $_GET['code']]);
echo "still going...";
// The provider provides a way to get an authenticated API request for
// the service, using the access token; it returns an object conforming
// to Psr\Http\Message\RequestInterface.
$request1 = $provider->getAuthenticatedRequest(
Fitbit::METHOD_GET,
Fitbit::BASE_FITBIT_API_URL . '/1/user/-/profile.json',
$accessToken,
['headers' => [Fitbit::HEADER_ACCEPT_LANG => 'en_US'], [Fitbit::HEADER_ACCEPT_LOCALE => 'en_US']]
// Fitbit uses the Accept-Language for setting the unit system used
// and setting Accept-Locale will return a translated response if available.
// https://dev.fitbit.com/docs/basics/#localization
);
// Make the authenticated API request and get the parsed response.
$response1 = $provider->getParsedResponse($request1);
//eventually will set variables here...
$deviceSpecificID=$response1['user']['encodedId'];
$firstName=$response1['user']['firstName'];
$lastName=$response1['user']['lastName'];
//making repeat request to get more data
$request2 = $provider->getAuthenticatedRequest(
Fitbit::METHOD_GET,
Fitbit::BASE_FITBIT_API_URL . '/1/user/-/activities/date/2017-09-23.json',
$accessToken,
['headers' => [Fitbit::HEADER_ACCEPT_LANG => 'en_US'], [Fitbit::HEADER_ACCEPT_LOCALE => 'en_US']]);
$response2=$provider->getParsedResponse($request2);
$stepsToday=$response2['summary']['steps'];
$stepGoal=$response2['goals']['steps'];
$todaysDate=date("Y-m-d");
//add variables to the session
$_SESSION['loggedin']=True;
$_SESSION['device']="fitbit";
$_SESSION['deviceSpecificID']=$deviceSpecificID;
$_SESSION['firstName'] = $firstName;
$_SESSION['lastName']=$lastName;
$_SESSION['activityArray']=$activityArray;
$_SESSION['steps']=$stepsToday;
$_SESSION['dailyGoal']=$stepGoal;
$_SESSION['todaysDate']=$todaysDate;
} catch (\League\OAuth2\Client\Provider\Exception\IdentityProviderException $e) {
// Failed to get the access token or user details.
exit($e->getMessage());
}
}
?>
I'm fairly confident that I've deduced the error is being thrown when running the line:
$accessToken = $provider->getAccessToken('authorization_code', ['code' => $_GET['code']]);
Any ideas why the error of "Forbidden" would show up? I'm not getting any php errors on my cgi_error log in my webhost's control panel.
Thank you so much in advance. I'm near pulling my hair out, and I'm not sure where to go from here.
Brett

Slack Oauth integration with adam-paterson/oauth2-slack

I am trying to use the Admin-paterson oauth library for PHP to connect to slack
(https://github.com/adam-paterson/oauth2-slack)
When I run the sample code:
include("slack-vendor/autoload.php");
include("slacker/src/Provider/Slack.php");
$provider = new \AdamPaterson\OAuth2\Client\Provider\Slack([
'clientId' => $$slackid,
'clientSecret' => $slacksecret,
'redirectUri' => $returnURL,
]);
if (!isset($_GET['code'])) {
// If we don't have an authorization code then get one
$authUrl = $provider->getAuthorizationUrl();
$_SESSION['oauth2state'] = $provider->getState();
header('Location: '.$authUrl);
exit;
// Check given state against previously stored one to mitigate CSRF attack
} elseif (empty($_GET['state']) || ($_GET['state'] !== $_SESSION['oauth2state'])) {
unset($_SESSION['oauth2state']);
exit('Invalid state');
} else {
// Try to get an access token (using the authorization code grant)
$token = $provider->getAccessToken('authorization_code', [
'code' => $_GET['code']
]);
// Optional: Now you have a token you can look up a users profile data
try {
// We got an access token, let's now get the user's details
$team = $provider->getResourceOwner($token);
// Use these details to create a new profile
printf('Hello %s!', $team->getName());
} catch (Exception $e) {
// Failed to get user details
exit('Oh dear...');
}
// Use this to interact with an API on the users behalf
echo $token->getToken();
}
I get an error back from slack saying :
Invalid permissions requested
Requested scopes cannot be blank
I tried adding a "scope" to the call like this:
$provider = new \AdamPaterson\OAuth2\Client\Provider\Slack([
'clientId' => $slackid,
'clientSecret' => $slacksecret,
'redirectUri' => $returnURL,
'scope' => 'channels:write,groups:write,team:read'
]);
but it still returns the same error.
When I look at the url the scope field is blank
what do I need to do to send scope to the server?
Add your scope in getAuthorizationUrl() method like this
$authUrl = $provider->getAuthorizationUrl([
'scope' => 'channels:write'
]);
use the scope as defined in https://api.slack.com/apps/ in your App, under OAuth, e.g. 'scope' => 'users.profile:read'

Fi-ware IDM - Oauth2 php client configuration

I'm trying to use the FiWare Identity Management - KeyRock that provides a Oauth 2.0 login. I have configured my app in the Fiware web page to set the url and callback url and I have got my client ID and my password.
Now I'm trying to use the API with a simple PHP client Oauth2.0 library. I've choosen this. It looks very easy to use, but I have a problem:
When I open my web, I'm correctly redirected to the fi-ware login web page, but once i logged, I'm not redirected to my web page callback page, I continue in the fi-ware labs web page.
That's my code:
index.php:
<?php
require_once 'vendor/autoload.php';
use fkooman\OAuth\Client\Guzzle6Client;
use fkooman\OAuth\Client\ClientConfig;
use fkooman\OAuth\Client\SessionStorage;
use fkooman\OAuth\Client\Api;
use fkooman\OAuth\Client\Context;
$clientConfig = new ClientConfig(
array(
'authorize_endpoint' => 'https://account.lab.fi-ware.org',
'client_id' => 'my_client_id',
'client_secret' => 'my_secret',
'token_endpoint' => 'http://estebanxabi.miwp.eu/otros/callback.php',
)
);
$tokenStorage = new SessionStorage();
$httpClient = new Guzzle6Client();
$api = new Api('foo', $clientConfig, $tokenStorage, $httpClient);
$context = new Context('sampleEmail', array('authorizations'));
$accessToken = $api->getAccessToken($context);
if (false === $accessToken) {
/* no valid access token available, go to authorization server */
header('HTTP/1.1 302 Found');
header('Location: '.$api->getAuthorizeUri($context));
exit;
}
echo 'Access Token: '.$accessToken->getAccessToken();
and callback.php:
<?php
require_once 'vendor/autoload.php';
use fkooman\OAuth\Client\Guzzle6Client;
use fkooman\OAuth\Client\ClientConfig;
use fkooman\OAuth\Client\SessionStorage;
use fkooman\OAuth\Client\Callback;
$clientConfig = new ClientConfig(
array(
'authorize_endpoint' => 'https://account.lab.fi-ware.org',
'client_id' => 'client_ide',
'client_secret' => 'seceret',
'token_endpoint' => 'http://estebanxabi.miwp.eu/otros/callback.php',
)
);
try {
$tokenStorage = new SessionStorage();
$httpClient = new Guzzle6Client();
$cb = new Callback('foo', $clientConfig, $tokenStorage, $httpClient);
$cb->handleCallback($_GET);
header('HTTP/1.1 302 Found');
header('Location: http://localhost/fkooman/php-oauth-client/example/simple6/index.php');
exit;
} catch (fkooman\OAuth\Client\Exception\AuthorizeException $e) {
// this exception is thrown by Callback when the OAuth server returns a
// specific error message for the client, e.g.: the user did not authorize
// the request
die(sprintf('ERROR: %s, DESCRIPTION: %s', $e->getMessage(), $e->getDescription()));
} catch (Exception $e) {
// other error, these should never occur in the normal flow
die(sprintf('ERROR: %s', $e->getMessage()));
}
I've never use that library, but taking a look... are you sure "token_endpoint" is correctly configured? It is not the same the token endpoint (/oauth2/token) than the callback URL.
BR

Authenticate access token provided by GoogleAuthUtil.getToken after sending it to php web server

I am following the docs from link below:
https://developers.google.com/+/mobile/android/sign-in#enable_server-side_api_access_for_your_app
Specifically the part that says:
If you do not require offline access, you can retrieve the access token and send it to your server over a secure connection. You can obtain the access token directly using GoogleAuthUtil.getToken() by specifying the scopes without your server's OAuth 2.0 client ID. For example:
I retrieve the access token like this:
accessToken = GoogleAuthUtil.getToken(
AuthenticatorActivity.this,
Plus.AccountApi.getAccountName(Common.mGoogleApiClient),
"oauth2:https://www.googleapis.com/auth/plus.me https://www.googleapis.com/auth/plus.login email"
);
After I retrieve the access token I send it to a web server, on the web server i can see that it's a valid access token by calling
https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.$_POST['google_access_token']
The request above returns the android apps client id, it also returns the users email correctly.
The problem is that when I try to run $client->authenticate($_POST['google_access_token']); I get an exception with the message: "invalid_grant: Incorrect token type".
To prevent getToken caching I always invalidate the token in android app:
if (accessToken != null && !accessToken.isEmpty()) {
GoogleAuthUtil.invalidateToken(AuthenticatorActivity.this, accessToken);
}
Here's the php code:
if (!isset($_POST['google_access_token'])) {
throw new Exception('missing google_access_token');
}
$client = new \Google_Client();
$client->setApplicationName("GiverHub");
$client->setClientId($this->config->item('google_client_id'));
$client->setClientSecret($this->config->item('google_client_secret'));
$client->setDeveloperKey($this->config->item('google_developer_key'));
$client->setRedirectUri($this->config->item('google_redirect_uri'));
$client->setScopes([
'https://www.googleapis.com/auth/plus.login',
'https://www.googleapis.com/auth/plus.me',
'email',
]);
try {
$client->authenticate($_POST['google_access_token']); // if i remove this the rest of the code below works! ...
$reqUrl = 'https://www.googleapis.com/oauth2/v1/tokeninfo?access_token='.$_POST['google_access_token'];
$req = new \Google_Http_Request($reqUrl);
$io = $client->getIo();
$response = $io->executeRequest($req);
$response = $response[0];
$response = json_decode($response, true);
if ($response === null) {
throw new Exception('Failed to check token. response null');
}
if ($response['issued_to'] !== '466530377541-s7cfm34jpf818gbr0547pndpq9songkg.apps.googleusercontent.com') {
throw new Exception('Invalid access token. issued to wrong client id: '. print_r($response, true));
}
if (!isset($response['user_id'])) {
throw new Exception('Missing user_id');
}
if (!isset($response['email'])) {
throw new Exception('Missing email');
}
/** #var \Entity\User $user */
$user = Common::create_member_google([
'id' => $response['user_id'],
'email' => $response['email'],
'given_name' => '',
'family_name' => '',
]);
$user->login($this->session);
if ($user instanceof \Entity\User) {
echo json_encode( [ 'success' => true, 'user' => $user ] );
} else {
echo json_encode( [ 'success' => false, 'msg' => $user ] );
}
} catch(Exception $e) {
echo json_encode(['success' => false, 'msg' => $e->getMessage()]);
}
The above code works if i remove the $client->authenticate(); line ... The problem is that I can't get the given_name / family_name etc .. only email / google_user_id from the tokeninfo ...
Any thoughts about why the key works for tokeninfo but not for authenticate?
I have tried many different variations of the scopes .. both on the server side and the android side ..
The $client->authenticate() method doesn't quite do what you're trying to do. It takes a one-time code from an earlier OAuth transaction and exchanges it for the access token. In your case - you're saying you already have the access token.
You should be able to call $client->setAccessToken() to set the token instead, so it may look something like
$client->setAccessToken($_POST['google_access_token']);
This is the solution I came up with after user158443 suggested I use $client->setAccessToken();
// first json_encode the access token before sending it to $client->setAccessToken();
$json_encoded_access_token = json_encode([
'access_token' => $_POST['google_access_token'],
'created' => time(), // make up values for these.. otherwise the client thinks the token has expired..
'expires_in' => time()+60 // made up a value in the future...
]);
// and then set it
$client->setAccessToken($json_encoded_access_token);
// and then get userinfo or whatever you want from google api !! :)
$oauth2 = new \Google_Service_Oauth2($client);
$user_info = $oauth2->userinfo->get();
NOTE: it's probably not smart to "emulate" the expires_in and created that i just did if you are in production ... You should probably call tokeninfo first and get the expires time from there...
NOTE: I still have no idea how to get a refresh token for this... but I don't need one for my use case..

Categories