I want to add google oauth to my web app, i already follow the google documentation about google oauth with php client library, but i got problem
Here my code
public function googleOauth() {
$client = new Google_Client();
$client->setAuthConfig(base_path('google_client.json'));
//$client->setAccessType("offline");
$client->setIncludeGrantedScopes(true);
$client->addScope(Google_Service_Blogger::BLOGGER);
$client->setRedirectUri(route('googleOauthCallback'));
return redirect($client->createAuthUrl());
}
public function googleOauthCallback(Request $params) {
if ($params->code) {
$client = new Google_Client();
$client->authenticate($params->code);
dd($client->getAccessToken());
}
But the $client->getAccessToken() return null
How to fix it ?
Related
I'm trying to get a Google access token for a service account so I can access the Analytics API from the client side.
On the server side I have the following code:
$keyFile = base_path() . '/keys/xxxxxxxx-xxxxxxxxx.json';
$client = new Google_Client();
$client->setApplicationName('Analytics Demo');
$client->setAuthConfig($keyFile);
$client->setScopes(['https://www.googleapis.com/auth/analytics.readonly']);
$token = $client->getAccessToken(); // Returns null
At some point it returned a token, but after a couple of calls it started returning null.
Trying to get the $client->getRefreshToken() also returns null.
When I put $client in a Google_Service_Analytics object everything seems to work just fine, so I know the key file is correct and properly read:
$analytics = new Google_Service_Analytics($client);
$accounts = $analytics->management_accounts->listManagementAccounts(); // Returns proper data
Any ideas on what might be going wrong?
UPDATE:
Calling $client->isAccessTokenExpired() results in true so I guess I have to refresh the token, but I have no clue how.
After a lot of trial and error I found that I had to use $client->fetchAccessTokenWithAssertion() instead of $client->getAccessToken().
public static function getGoogleServiceToken():?string {
$keyFile = base_path() . '/keys/xxxxxxxx-xxxxxxx.json';
$client = new Google_Client();
$client->setAuthConfig($keyFile);
$client->setApplicationName('Analytics Demo');
$client->setAccessType('access_type');
$client->setScopes(['https://www.googleapis.com/auth/analytics.readonly']);
if ($client->isAccessTokenExpired()) {
$token = $client->fetchAccessTokenWithAssertion();
}
else {
$token = $client->getAccessToken();
}
return $token['access_token'];
}
Client side:
...
private _handleGetResponse(response) {
...
gapi.analytics.auth.authorize({
serverAuth: {
access_token: response.token,
}
});
...
Not sure why there is no decent documentation on this at all. Even knowing that I have to use this method I can't find documentation on what this method is actually doing. Any explanation or links to some documentation are still welcome!
I'm just starting with google OAuth using the PHP Client Library. I'm having trouble getting the example from the Google APIs site working. Google's Example
When i try to exchange the authorization code for a token, it just returns NULL. No errors or exceptions.
I thought maybe it was a problem with my client_secret.json, but I don't know what to look for.
Here's my full code:
$client = new \Google_Client();
$client->setAuthConfig('client_secret.json');
$client->setRedirectUri('http://localhost/test.php');
$client->setAccessType('offline');
$client->addScope(\Google_Service_Gmail::MAIL_GOOGLE_COM);
if (! isset($request->code)) {
return redirect($client->createAuthUrl());
} else {
$client->authenticate($request->code);
$token = $client->getAccessToken(); // <- returns NULL, but no execeptions or errors
dd($token);
return redirect('https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=' . $token);
}
I wrote a method to get the Google client and refresh the token file when needed. However $client->isAccessTokenExpired() always returns true, so every request a new token gets dumped.
I have already read this question. The answer does not apply to me. I already do the steps in the right order.
Hopefully someone can steer me in the right direction.
/**
* Initialize Google Client and return it
* #return Client
*/
private function getClient()
{
if ( $this->client !== null ) {
return $this->client;
}
$client = new Client();
$client->setClientId($this->google_client_id);
$client->setClientSecret($this->google_client_secret);
$client->setAccessType('offline');
$client->setApprovalPrompt('force');
$client->setAccessToken(file_get_contents($this->google_token));
if($client->isAccessTokenExpired()) {
try {
$fs = new FileSystem();
$fs->dumpFile($this->google_token, json_encode($client->getAccessToken()));
$this->logger->info(sprintf('Dumped new Google OAuth token in: %s', $this->google_token));
} catch(IOException $e) {
$this->logger->critical(sprintf('Error dumping new Google OAuth token: %s', $e->getMessage());
}
}
$this->client = $client;
return $this->getClient();
}
I am creating google client instance and authenticating it once and fetching required data. Afterwards if I want to use that same instance of Google client for some other service , how can I achieve it ?
webmasterMain route is my redirect uri registered in google webmaster .
public function webmasterMain(Request $request)
{
$requestData = $request->all();
if ($request->isMethod('POST') || isset($requestData['code'])) {
$google_redirect_url = env('APP_URL') . '/user/webmasterMain';
$gClient = new \Google_Client();
$gClient->setAccessType("offline");// to get refresh token after expiration of access token
$gClient->setIncludeGrantedScopes(true); // incremental auth
$gClient->setApplicationName(config('services.google.app_name'));
$gClient->setClientId(config('services.google.client_id'));
$gClient->setClientSecret(config('services.google.client_secret'));
$gClient->setRedirectUri($google_redirect_url);
$gClient->setDeveloperKey(config('services.google.api_key'));
$gClient->setScopes(array(
'https://www.googleapis.com/auth/plus.me',
'https://www.googleapis.com/auth/userinfo.email',
'https://www.googleapis.com/auth/userinfo.profile',
'https://www.googleapis.com/auth/webmasters.readonly',
'https://www.googleapis.com/auth/webmasters',
));
$google_oauthV2 = new \Google_Service_Oauth2($gClient);
if ($request->get('code')) {
$gClient->authenticate($request->get('code'));
$request->session()->put('token', $gClient->getAccessToken());
}
if ($request->session()->get('token')) {
$gClient->setAccessToken($request->session()->get('token'));
}
if ($gClient->getAccessToken()) {
$inst = new Google_Service_Webmasters($gClient);
$res = $inst->sites->listSites();
$sites = $res->getSiteEntry();
$siteUrl = [];
foreach ($sites as $key => $site) {
$siteUrl = array_add($siteUrl, $key, ['site_name'=>$site['siteUrl'], 'site_permission_level' => $site['permissionLevel']]);
}
$sites = (((array)$siteUrl));
return view('User::webmasterMain')->with(['data' => $sites]);
} else {
//For Guest user, get google login url
$authUrl = $gClient->createAuthUrl();
return redirect()->to($authUrl);
}
}
return view('User::webmasterMain');
}
Now suppose I want to get the authenticated $gClient for service like Google_Service_Webmasters_SearchAnalyticsQueryRequest , then how can I make $client = $gClient for this next request ?
public function query(Request $request){
//suppose $client is the same instance which was previously authenticated and stored in $gClient
$website = "http://example.com/";
$searchAnalytics = new \Google_Service_Webmasters_SearchAnalyticsQueryRequest();
$searchAnalytics->setStartDate('2017-03-01');
$searchAnalytics->setEndDate('2017-03-31');
$searchAnalytics->setDimensions(['page']);
$searchAnalytics->setSearchType('web');
`$results = $client->searchanalytics->query($website, $searchAnalytics);`
return $results->getRows();
I got the answer , no need to save the instance or do anything but, follow this :
Create a Google Client Object.
At first time authenticating save the accessToken from google client object by getAccessToken().
Use the same access token and set Access token in this google client.
now you can use this google client object for any service.
First time authenticating:
$gClient = new \Google_Client();
//after authenticating
$request->session()->put('token', $gClient->getAccessToken());
Now we can use this access token in any google service call:
$gClient = new \Google_Client();
if ($request->session()->get('token')) {
$gClient->setAccessToken($request->session()->get('token'));
}
$client = new Google_Service_Webmasters($gClient);
I'm using codeigniter 3.x and php 5.5+. I've been trying to get this to work with no luck. I want to call methods inside a youtube controller class I created that will do different things based on communicating with the google or youtube. The problem is with the Google_Client I believe or it's with how to store $client variable maybe so you can use it in second function. When I try calling this from another function it gives a not login required error even thought the user already did the google verification. How can I tell my second function that the user has already done the authorization and got the token. Everything seems to work very well when both functions are in the same function(I mean just using one function). Also I don't want to verify user on every function or method I execute.
So after first function is done, I get redirected with an access token in the url to the second function but then I get an error Message: Error calling GET https://www.googleapis.com/youtube/analytics/v1/reports?ids=channel%3D%3DMINE&start-date=2014-01-01&end-date=2016-01-20&metrics=views&filters=video%3D%3DpC900o6JaMc: (401) Login Required
First function in the controller Youtubeverify:
class Youtubeverify extends CI_Controller{
public function youtube_consent(){
$this->load->library('google');
$OAUTH2_CLIENT_ID = 'MY_ID';
$OAUTH2_CLIENT_SECRET = 'MY_KEY';
$client = new Google_Client();
$client->setClientId($OAUTH2_CLIENT_ID);
$client->setClientSecret($OAUTH2_CLIENT_SECRET);
$client->setScopes(array('https://www.googleapis.com/auth/yt-analytics-monetary.readonly','https://www.googleapis.com/auth/youtube.readonly'));
$redirect = filter_var('http://' . $_SERVER['HTTP_HOST'] . "/ci/youtubeverify/display_report",
FILTER_SANITIZE_URL);
$client->setRedirectUri($redirect);
$youtubeReporting = new Google_Service_YouTubeReporting($client);
if (isset($_REQUEST['logout'])) {
$this->session->unset_userdata('youtube_token');
}
if (isset($_GET['code'])) {
if (strval($_SESSION['state']) !== strval($_GET['state'])) {
die('The session state did not match.');
}
$client->authenticate($_GET['code']);
$youtube_token = $client->getAccessToken();
//trying to store the access token in a session
$newdata = array('youtube_token'=>$youtube_token);
$this->session->set_userdata($newdata);
header('Location: ' . $redirect);
}
if ($this->session->userdata('youtube_token')) {
$client->setAccessToken($this->session->userdata('youtube_token'));
}
if ($client->getAccessToken()) {
$client->getAccessToken();
}
else {
// If the user hasn't authorized the app, initiate the OAuth flow
$state = mt_rand();
$client->setState($state);
$_SESSION['state'] = $state;
$authUrl = $client->createAuthUrl();
redirect($authUrl);
}
}
Second function in the controller Youtubeverify:
public function display_report(){
$this->load->library('google');
$client = new Google_Client();
$client->getAccessToken();
$youtubeAnalytics = new Google_Service_YouTubeAnalytics($client);
$id = 'channel==MINE';
$start_date = '2014-01-01';
$end_date = '2016-01-20';
$optparams = array('filters' => 'video==*********');
$metrics = array('views');
$api_response = $metrics;
$api = $youtubeAnalytics->reports->query($id, $start_date, $end_date, $metric,$optparams);
$data['api_response'] = $api_response['views'];
$this->load->view('layouts/mainlay',$data);
}
I have never worked with YouTube API before, but here's a step in the right direction.
class Youtubeverify extends CI_Controller {
// Google API Keys
const CLIENT_ID = '';
const CLIENT_SECRET = '';
// We'll store the client in a class property so we can access it between methods.
protected $Client;
public function __construct () {
parent::__construct();
// setup google client.
$this->Client = new Google_Client();
$this->Client->setClientId(self::CLIENT_ID);
$this->Client->setClientSecret(self::CLIENT_SECRET);
// we call the authenication method for each request
$this->_authenticate_client();
}
// Authentication method
protected function _authenticate_client () {
//if we already have a token then we just set it in the client
//without going through authentication process again
if( $accessToken = $this->session->userdata('youtube_token') ) {
$this->Client->setAccessToken($accessToken);
}else{
// preform authentication as usual with a redirect ...etc
}
}
}