I am trying to login using google+ .But getting
That’s an error.
Error: invalid_client
The OAuth client was not found.
Request Details
access_type=offline
openid.realm=
scope=https://www.googleapis.com/auth/plus.login
origin=http://localhost
response_type=code permission
redirect_uri=storagerelay://http/localhost?id=auth929840
ss_domain=http://localhost
client_id={{ CLIENT_ID }}
I have double-checked the client id .Help would be appreciated
I have attached my index.php file.
<?php
/*
* Sample application for Google+ client to server authentication.
* Remember to fill in the OAuth 2.0 client id and client secret,
* which can be obtained from the Google Developer Console at
* https://code.google.com/apis/console
*
* Copyright 2013 Google Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Note (Gerwin Sturm):
* Include path is still necessary despite autoloading because of the require_once in the libary
* Client library should be fixed to have correct relative paths
* e.g. require_once '../Google/Model.php'; instead of require_once 'Google/Model.php';
*/
set_include_path(get_include_path() . PATH_SEPARATOR . __DIR__ .'/vendor/google/apiclient/src');
require_once __DIR__.'/vendor/autoload.php';
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
/**
* Simple server to demonstrate how to use Google+ Sign-In and make a request
* via your own server.
*
* #author silvano#google.com (Silvano Luciani)
*/
/**
* Replace this with the client ID you got from the Google APIs console.
*/
const CLIENT_ID = 'XXXXXXXX-itqqmr9qhegol91ne7sgkkeksmncfgqp.apps.googleusercontent.com';
/**
* Replace this with the client secret you got from the Google APIs console.
*/
const CLIENT_SECRET = 'XXXXXXXXXXX';
/**
* Optionally replace this with your application's name.
*/
const APPLICATION_NAME = "CoachGator";
$client = new Google_Client();
$client->setApplicationName(APPLICATION_NAME);
$client->setClientId(CLIENT_ID);
$client->setClientSecret(CLIENT_SECRET);
$client->setRedirectUri('postmessage');
$plus = new Google_Service_Plus($client);
$app = new Silex\Application();
$app['debug'] = true;
$app->register(new Silex\Provider\TwigServiceProvider(), array(
'twig.path' => __DIR__,
));
$app->register(new Silex\Provider\SessionServiceProvider());
// Initialize a session for the current user, and render index.html.
$app->get('/', function () use ($app) {
$state = md5(rand());
$app['session']->set('state', $state);
return $app['twig']->render('index.html', array(
'CLIENT_ID' => CLIENT_ID,
'STATE' => $state,
'APPLICATION_NAME' => APPLICATION_NAME
));
});
// Upgrade given auth code to token, and store it in the session.
// POST body of request should be the authorization code.
// Example URI: /connect?state=...&gplus_id=...
$app->post('/connect', function (Request $request) use ($app, $client) {
$token = $app['session']->get('token');
if (empty($token)) {
// Ensure that this is no request forgery going on, and that the user
// sending us this connect request is the user that was supposed to.
if ($request->get('state') != ($app['session']->get('state'))) {
return new Response('Invalid state parameter', 401);
}
// Normally the state would be a one-time use token, however in our
// simple case, we want a user to be able to connect and disconnect
// without reloading the page. Thus, for demonstration, we don't
// implement this best practice.
//$app['session']->set('state', '');
$code = $request->getContent();
// Exchange the OAuth 2.0 authorization code for user credentials.
$client->authenticate($code);
$token = json_decode($client->getAccessToken());
// You can read the Google user ID in the ID token.
// "sub" represents the ID token subscriber which in our case
// is the user ID. This sample does not use the user ID.
$attributes = $client->verifyIdToken($token->id_token, CLIENT_ID)
->getAttributes();
$gplus_id = $attributes["payload"]["sub"];
// Store the token in the session for later use.
$app['session']->set('token', json_encode($token));
$response = 'Successfully connected with token: ' . print_r($token, true);
} else {
$response = 'Already connected';
}
return new Response($response, 200);
});
// Get list of people user has shared with this app.
$app->get('/people', function () use ($app, $client, $plus) {
$token = $app['session']->get('token');
if (empty($token)) {
return new Response('Unauthorized request', 401);
}
$client->setAccessToken($token);
$people = $plus->people->listPeople('me', 'visible', array());
/*
* Note (Gerwin Sturm):
* $app->json($people) ignores the $people->items not returning this array
* Probably needs to be fixed in the Client Library
* items isn't listed as public property in Google_Service_Plus_Person
* Using ->toSimpleObject for now to get a JSON-convertible object
*/
return $app->json($people->toSimpleObject());
});
// Revoke current user's token and reset their session.
$app->post('/disconnect', function () use ($app, $client) {
$token = json_decode($app['session']->get('token'))->access_token;
$client->revokeToken($token);
// Remove the credentials from the user's session.
$app['session']->set('token', '');
return new Response('Successfully disconnected', 200);
});
$app->run();
Related
I recently changed my DocuSign integration to use the JWT OAuth flow. To achieve this I have a few classes.
OAuth Client
<?php
namespace App\DocuSign;
use DocuSign\eSign\Client\ApiClient;
use DocuSign\eSign\Client\Auth\OAuth;
use DocuSign\eSign\Configuration;
use Exception;
use Illuminate\Support\Facades\Log;
/**
* Helper class to generate a DocuSign Client instance using JWT OAuth2.
*
* #see
*
*/
class OAuthClient
{
/**
* Create a new DocuSign API Client instance using JWT based OAuth2.
*/
public static function createApiClient()
{
$config = (new Configuration())->setHost(config('docusign.host'));
$oAuth = (new OAuth())->setOAuthBasePath(config('docusign.oauth_base_path'));
$apiClient = new ApiClient($config, $oAuth);
try {
$response = $apiClient->requestJWTUserToken(
config('docusign.integrator_key'),
config('docusign.user_id'),
config('docusign.private_key'),
'signature impersonation',
60
);
if ($response) {
$accessToken = $response[0]['access_token'];
$config->addDefaultHeader('Authorization', 'Bearer ' . $accessToken);
$apiClient = new ApiClient($config);
return $apiClient;
}
} catch (Exception $e) {
// If consent is required we just need to give the consent URL.
if (strpos($e->getMessage(), 'consent_required') !== false) {
$authorizationUrl = config('docusign.oauth_base_path') . '/oauth/auth?' . http_build_query([
'scope' => 'signature impersonation',
'redirect_uri' => config('docusign.redirect_url'),
'client_id' => config('docusign.integrator_key'),
'response_type' => 'code'
]);
Log::critical('Consent not given for DocuSign API', [
'authorization_url' => $authorizationUrl
]);
abort(500, 'Consent has not been given to use the DocuSign API');
}
throw $e;
}
}
}
Signature Client Service
<?php
namespace App\DocuSign;
use DocuSign\eSign\Api\EnvelopesApi;
use DocuSign\eSign\Client\ApiClient;
class SignatureClientService
{
/**
* DocuSign API Client
*/
public ApiClient $apiClient;
/**
* Create a new instance of our class.
*/
public function __construct()
{
$this->apiClient = OAuthClient::createApiClient();
}
/**
* Getter for the EnvelopesApi
*/
public function getEnvelopeApi(): EnvelopesApi
{
return new EnvelopesApi($this->apiClient);
}
}
Then, in my constructors where I want to use it I'm doing
/**
* Create a new controller instance
*/
public function __construct()
{
$this->clientService = new SignatureClientService();
$this->envelopesApi = $this->clientService->getEnvelopeApi();
}
Finally, I use it like so
$envelopeSummary = $this->envelopesApi->createEnvelope(config('docusign.api_account_id'), $envelopeDefinition);
But I get an error that reads
DocuSign\eSign\Client\ApiException: Error while requesting server,
received a non successful HTTP code [400] with response Body:
O:8:"stdClass":2:{s:9:"errorCode";s:21:"USER_LACKS_MEMBERSHIP";s:7:"message";s:60:"The
UserID does not have a valid membership in this Account.";} in
/homepages/45/d641872465/htdocs/sites/ita-portal/vendor/docusign/esign-client/src/Client/ApiClient.php:344
I researched this and this would imply that the user is not within the account, but they are. I also checked that this account owns the envelopes that I'm trying to send.
For reference I took inspiration for envelope sending from here: https://developers.docusign.com/docs/esign-rest-api/how-to/request-signature-template-remote/
What I think is happening is that the request is going to the wrong server or the wrong account.
I'd suggest using a packet analyser like Fiddler or Wireshark to log where your requests are headed (or just log the request within your application)
The auth URLs seem to be correct since you're not getting a 401 unauthorised error but the envelopes and other queries' must match the base URL located in your account under the Apps and Keys page. It would be of the form demo.docusign.net for our demo environment or xxx.docusign.net for our production environment
I need to send emails from contact forms using Gmail SMTP through a GSuite account. I tested everything on local machine and everything worked. But after deployment I can't generate the refresh token correctly. Here is the code I am running on the server.
<?php
/**
* PHPMailer - PHP email creation and transport class.
* PHP Version 5.5
* #package PHPMailer
* #see https://github.com/PHPMailer/PHPMailer/ The PHPMailer GitHub project
* #author Marcus Bointon (Synchro/coolbru) <phpmailer#synchromedia.co.uk>
* #author Jim Jagielski (jimjag) <jimjag#gmail.com>
* #author Andy Prevost (codeworxtech) <codeworxtech#users.sourceforge.net>
* #author Brent R. Matzelle (original founder)
* #copyright 2012 - 2017 Marcus Bointon
* #copyright 2010 - 2012 Jim Jagielski
* #copyright 2004 - 2009 Andy Prevost
* #license http://www.gnu.org/copyleft/lesser.html GNU Lesser General Public License
* #note This program is distributed in the hope that it will be useful - WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE.
*/
/**
* Get an OAuth2 token from an OAuth2 provider.
* * Install this script on your server so that it's accessible
* as [https/http]://<yourdomain>/<folder>/get_oauth_token.php
* e.g.: http://localhost/phpmailer/get_oauth_token.php
* * Ensure dependencies are installed with 'composer install'
* * Set up an app in your Google/Yahoo/Microsoft account
* * Set the script address as the app's redirect URL
* If no refresh token is obtained when running this file,
* revoke access to your app and run the script again.
*/
namespace PHPMailer\PHPMailer;
/**
* Aliases for League Provider Classes
* Make sure you have added these to your composer.json and run `composer install`
* Plenty to choose from here:
* #see http://oauth2-client.thephpleague.com/providers/thirdparty/
*/
// #see https://github.com/thephpleague/oauth2-google
use League\OAuth2\Client\Provider\Google;
// #see https://packagist.org/packages/hayageek/oauth2-yahoo
use Hayageek\OAuth2\Client\Provider\Yahoo;
// #see https://github.com/stevenmaguire/oauth2-microsoft
use Stevenmaguire\OAuth2\Client\Provider\Microsoft;
if (!isset($_GET['code']) && !isset($_GET['provider'])) {
?>
<html>
<body>Select Provider:<br/>
<a href='?provider=Google'>Google</a><br/>
<a href='?provider=Yahoo'>Yahoo</a><br/>
<a href='?provider=Microsoft'>Microsoft/Outlook/Hotmail/Live/Office365</a><br/>
</body>
</html>
<?php
exit;
}
require '/home4/findynoy/public_html/i3minds.co.in/vendor/autoload.php';
session_start();
$providerName = '';
if (array_key_exists('provider', $_GET)) {
$providerName = $_GET['provider'];
$_SESSION['provider'] = $providerName;
} elseif (array_key_exists('provider', $_SESSION)) {
$providerName = $_SESSION['provider'];
}
if (!in_array($providerName, ['Google', 'Microsoft', 'Yahoo'])) {
exit('Only Google, Microsoft and Yahoo OAuth2 providers are currently supported in this script.');
}
//These details are obtained by setting up an app in the Google developer console,
//or whichever provider you're using.
$clientId = '637142774117-v1j200em1eh9ug52nmhf9u2mh5cblp63.apps.googleusercontent.com';
$clientSecret = 'VI2CxFxlBLD0lGaJd9b4OX61';
//If this automatic URL doesn't work, set it yourself manually to the URL of this script
// $redirectUri = (isset($_SERVER['HTTPS']) ? 'https://' : 'http://') . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
$redirectUri = 'https://i3minds.co.in/get_oauth_token.php';
$params = [
'clientId' => $clientId,
'clientSecret' => $clientSecret,
'redirectUri' => $redirectUri,
'accessType' => 'offline'
];
$options = [];
$provider = null;
switch ($providerName) {
case 'Google':
$provider = new Google($params);
$options = [
'scope' => [
'https://mail.google.com/'
]
];
break;
case 'Yahoo':
$provider = new Yahoo($params);
break;
case 'Microsoft':
$provider = new Microsoft($params);
$options = [
'scope' => [
'wl.imap',
'wl.offline_access'
]
];
break;
}
if (null === $provider) {
exit('Provider missing');
}
if (!isset($_GET['code'])) {
// If we don't have an authorization code then get one
$authUrl = $provider->getAuthorizationUrl($options);
$_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']);
unset($_SESSION['provider']);
exit('Invalid state');
} else {
unset($_SESSION['provider']);
// Try to get an access token (using the authorization code grant)
$token = $provider->getAccessToken(
'authorization_code',
[
'code' => $_GET['code']
]
);
// Use this to interact with an API on the users behalf
// Use this to get a new access token if the old one expires
echo 'Refresh Token: ', $token->getRefreshToken();
}
This is what I receive from the server. I assume refresh token can't be empty. Any help would be appreciated.
Probably you solved case, but from documentation, google return refresh token first time only, later if it's not changed, it's not returned.
You need to save it.
i have stuck on displaying Google Analytics specific page view a few days, from referring on the hello analytics.
I have try to modify it to everybody can view without login gmail in specific web page(using autoload to taking accessToken), below are the code :
<?php
session_start();
require_once 'google-api-php-client-2.2.1/vendor/autoload.php';
$accessToken = initializeAnalytics();
function initializeAnalytics()
{
$KEY_FILE_LOCATION ='Testing-58a019909c51.json';
$client = new Google_Client();
$client -> setApplicationName("testing");
$client -> setAuthConfig($KEY_FILE_LOCATION);
$client -> setScopes(['https://www.googleapis.com/auth/analytics.readonly']);
$client -> refreshTokenWithAssertion();
$client -> setAccessType("offline");
$client -> setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/testing-embed.php');
$token = $client->getAccessToken();
$accessToken = $token['access_token'];
return $accessToken;
}
//echo $accessToken;
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>
<h1>View</h1>
<div id="test123"></div>
<script type="text/javascript">
(function(w,d,s,g,js,fs){
g=w.gapi||(w.gapi={});g.analytics={q:[],ready:function(f){this.q.push(f);}};
js=d.createElement(s);fs=d.getElementsByTagName(s)[0];
js.src='https://apis.google.com/js/platform.js';
fs.parentNode.insertBefore(js,fs);js.onload=function(){g.load('analytics');};
}(window,document,'script'));
</script>
<script type="text/javascript">
gapi.analytics.ready(function() {
/**
* Authorize the user immediately if the user has already granted access.
* If no access has been created, render an authorize button inside the
* element with the ID "embed-api-auth-container".
*/
gapi.analytics.auth.authorize({
'serverAuth': {
'access_token': '<?php echo $accessToken ?>'
}
});
function queryCoreReportingApi(profileId) {
gapi.client.analytics.data.ga.get({
'ids': 'ga:168634971',
'start-date': '30daysAgo',
'end-date': 'today',
'metrics': 'ga:pageviews',
'filters': 'ga:pagePath==/xxx'
})
.then(function(response) {
var formattedJson = JSON.stringify(response.result, null, 2);
var json = JSON.parse(formattedJson);
var shares = parseInt(json.totalsForAllResults['ga:pageviews']);
document.getElementById('test123').append(shares);
})
.then(null, function(err) {
console.log(err);
});
}
});
</script>
</body>
</html>
can anybody tell me what wrong of the code? Thanks for Help!
Assuming that you have access to the Google Analytics account in question the easest way to do this would be to use a service account rather than oauth2. If you create service account credeitnals then take the service acccount email address and add it as a user in the admin section of google analytics at the account level it will have access to read from the Google Analytics api without requireing login
Service account auth link to code
require_once __DIR__ . '/vendor/autoload.php';
// Use the developers console and download your service account
// credentials in JSON format. Place the file in this directory or
// change the key file location if necessary.
putenv('GOOGLE_APPLICATION_CREDENTIALS='.__DIR__.'/service-account.json');
/**
* Gets the Google client refreshing auth if needed.
* Documentation: https://developers.google.com/identity/protocols/OAuth2ServiceAccount
* Initializes a client object.
* #return A google client object.
*/
function getGoogleClient() {
return getServiceAccountClient();
}
/**
* Builds the Google client object.
* Documentation: https://developers.google.com/api-client-library/php/auth/service-accounts
* Scopes will need to be changed depending upon the API's being accessed.
* array(Google_Service_Analytics::ANALYTICS_READONLY, Google_Service_Analytics::ANALYTICS)
* List of Google Scopes: https://developers.google.com/identity/protocols/googlescopes
* #return A google client object.
*/
function getServiceAccountClient() {
try {
// Create and configure a new client object.
$client = new Google_Client();
$client->useApplicationDefaultCredentials();
$client->addScope([YOUR SCOPES HERE]);
return $client;
} catch (Exception $e) {
print "An error occurred: " . $e->getMessage();
}
}
Usage
require_once __DIR__ . '/vendor/autoload.php';
session_start();
require_once __DIR__ . '/ServiceAccount.php';
$client = getGoogleClient();
$service = new Google_Service_Analyticsreporting($client);
If you don't have access to add this user then you will need to work out saving the refresh token and reusing it. I recommend saving it in a file on the server someplace but you will have an issue if the refresh token ever stops working which can happen. I have a few samples on Oauth2 login with refresh token here
I've been trying to set up OAuth for Etsy to use in a project but having trouble even getting the login page to load using PhpoAuthLib. Highly likely my low level of knowledge regarding the use of Oauth.
Currently this is my login page which is almost identical to the example given by the developer.
<?php
/**
* Example of retrieving an authentication token of the Etsy service
*
* PHP version 5.4
*
* #author Iñaki Abete <inakiabt+github#gmail.com>
* #copyright Copyright (c) 2013 The authors
* #license http://www.opensource.org/licenses/mit-license.html MIT License
*/
use OAuth\OAuth1\Service\Etsy;
use OAuth\Common\Storage\Session;
use OAuth\Common\Consumer\Credentials;
/**
* Bootstrap the example
*/
require_once 'OAuth/bootstrap.php';
// init contains my secret and key values
require_once 'OAuth/init.php';
// Session storage
$storage = new Session();
// Setup the credentials for the requests
$credentials = new Credentials(
$servicesCredentials['etsy']['key'],
$servicesCredentials['etsy']['secret'],
$currentUri->getAbsoluteUri()
);
// Instantiate the Etsy service using the credentials, http client and storage mechanism for the token
/** #var $etsyService Etsy */
$etsyService = $serviceFactory->createService('Etsy', $credentials, $storage);
if (!empty($_GET['oauth_token'])) {
$token = $storage->retrieveAccessToken('Etsy');
// This was a callback request from Etsy, get the token
$etsyService->requestAccessToken(
$_GET['oauth_token'],
$_GET['oauth_verifier'],
$token->getRequestTokenSecret()
);
// Send a request now that we have access token
$result = json_decode($etsyService->request('/private/users/__SELF__'));
echo 'result: <pre>' . print_r($result, true) . '</pre>';
} elseif (!empty($_GET['go']) && $_GET['go'] === 'go') {
$response = $etsyService->requestRequestToken();
$extra = $response->getExtraParams();
$url = $extra['login_url'];
header('Location: ' . $url);
} else {
$url = $currentUri->getRelativeUri() . '?go=go';
echo "<a href='$url'>Login with Etsy!</a>";
}
When running the page i get a fatal error of
Call to a member function getAbsoluteUri() on a non-object
I've been into the bootstrap.php and echoed a statement at the end which works fine so doesnt seem to be erroring there.
The error is on the line with
$currentUri->getAbsoluteUri()
not sure if it matters but the login page is located at mywebsite/folder/folder/etsylogin.php.. would this make any difference?
Hi guys i'm trying uploading file trought G drive API.
Can't find out why it returns error:
<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
class Gdrive{
function initialize(){
$credentials = $this->GetOAuth2Credentials($_GET['code']);
$_SESSION['credentials'] = $credentials;
}
/**
* Exchange an authorization code for OAuth 2.0 credentials.
*
* #param String $authorizationCode Authorization code to exchange for an
* access token and refresh token. The refresh token is only returned by
* Google on the very first exchange- when a user explicitly approves
* the authorization request.
* #return OauthCredentials OAuth 2.0 credentials object
*/
function GetOAuth2Credentials($authorizationCode) {
$client = new apiClient();
$client->setClientId(Config::5112+++++.apps.****5971157#developer.gserviceaccount.com);
$client->setRedirectUri(Config::site_url());
/**
* Ordinarily we wouldn't set the $_GET variable. However, the API library's
* authenticate() function looks for authorization code in the query string,
* so we want to make sure it is set to the correct value passed into the
* function arguments.
*/
$_GET['code'] = $authorizationCode;
$jsonCredentials = json_decode($client->authenticate());
$oauthCredentials = new OauthCredentials(
$jsonCredentials->access_token,
isset($jsonCredentials->refresh_token)?($jsonCredentials->refresh_token):null,
$jsonCredentials->created,
$jsonCredentials->expires_in,
Config::CLIENT_ID,
Config::CLIENT_SECRET
);
return $oauthCredentials;
}
function SaveNewFile($inputFile) {
try {
$mimeType = 'text/plain';
$file = new Google_DriveFile();
$file->setTitle($inputFile->title);
$file->setDescription($inputFile->description);
$file->setMimeType($mimeType);
// Set the parent folder.
if ($inputFile->parentId != null) {
$parentsCollectionData = new DriveFileParentsCollection();
$parentsCollectionData->setId($inputFile->parentId);
$file->setParentsCollection(array($parentsCollectionData));
}
$createdFile = $this->service->files->insert($file, array(
'data' => $inputFile->content,
'mimeType' => $mimeType,
));
return $createdFile;
} catch (apiServiceException $e) {
/*
* Log error and re-throw
*/
error_log('Error saving new file to Drive: ' . $e->getMessage(), 0);
throw $e;
}
}
}
when i invoke the initialize() method it returns error:
Message: Undefined index: code
Fatal error: Class 'apiClient' not found
what should be? i'm doing right in my code ? does i need more code to make it works? i created web application project on google api console.
need i to include google php sdk? in the google docs it is not mentioned for google drive api :/
You are probably using an older version of the PHP client library. Make sure you have the latest source and follow the instructions in the Google Drive SDK quickstart page to learn how to write a complete PHP app to upload a file to Drive:
https://developers.google.com/drive/quickstart
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();
please use those require files and Google_Client().