I am using a cross domain and uses php server to get user info when logging in. In my running website I use php code and when the user login I added this code
session_start();
Then just declare the user info when successfully logged in like:
$_SESSION['user_id'] = $user['user_id'];
$_SESSION['user_email'] = $user['user_email'];
$_SESSION['user_name'] = $user['user_name'];
And then I use that session $user['user_id']; in every user requests.
How to implement a session when the user logged on Hybrid app? Is it the same on how my running website works? Do I just need to add session code on the ajax request? Any idea?
To do this you need a host server that will authenticate and talk to your devices. Common protocols would be the use of cURL and JSON response:
REMOTE DEVICE
1) Your device, I will use another server because it's easy, will start a connection using cURL:
function cURL($variables = false)
{
$url = "http://www.example.com/";
$query = (!empty($variables))? '?'.http_build_query($variables) : '';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url.$query);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if(!empty($response))
$data = json_decode($response,true);
curl_close($ch);
return $data;
}
$login = cURL(array(
'service'=>'login',
'apikey'=>123123,
'username'=>'whatever',
'password'=>'whatever')
);
print_r($login);
API HOST SERVER
2) Your server then will be listening for services. I am using $_GET but $_POST is better:
if(!empty($_GET['service'])) {
switch($_GET['service']) {
case('login'):
logInUser($_GET);
}
}
The logInUser() function would just do the normal login function except that it would set timestamp, token, apikey, and username in the database and return that via json on success:
//...authentication code here...//
if($valid) {
// However you want to make a token
$token = md5($usename.mt_rand(1000000,9999999).time());
// Do code here to save the username, token, apikey, timestamp into database
// This will then echo back the token on success to the device
die(json_encode(array('token'=>$token,'success'=>true)));
}
else {
die(json_encode(array('token'=>'','success'=>'bad username/password')));
}
After this point, the device calls back to the host with the token in the query string as well as the apikey. It would also include a service and any variables that the service requires to send data back to the device. Every hit to the server triggers the server to look for an apikey, then service, then if service is not login, would require the token. It would query the database and check that all those things in the database are valid. If the token exists and the timestamp is recent enough (you can set the expiration time on that) then service runs. After service runs (or before complete), the timestamp value for the token is updated to current time.
Related
I built and maintain a PHP web application with an existing set of users. Authentication is username password, within the application.
There is now a requirement to provide access to a large new set of users, with existing Azure AD accounts. The client wants these users to be able to login using their Azure identities. The existing users would continue to authenticate the way they currently do.
I assumed this would be similar to Facebook/Google etc. SSO , but I'm struggling to find any examples of this in the Microsoft resources, or any libraries out there that will enable this. Is what I describe a valid use case, and achievable with Azuer AD Authentication?
Approach 1: Basically, to access the resources via Azure AD from PHP web application, you can refer to Web Application to Web API
To integrate Azure AD in PHP web applications, we need to follow authorization code grant flow steps to build several custom HTTP requests. E.G. To get access token via OAuth 2.0 protocol, we should refer to the steps on Authorization Code Grant Flow. generally, we will build 2 HTTP requests to get access token:
Request an authorization code.
Use the Authorization Code to Request an Access Token:
Please check this PHP test project for your reference
Approach 2 :
Please refer this github code:https://github.com/CoasterKaty/PHPAzureADoAuth
Try with these steps
Create app registration Azure AD > App registrations and click New registration.
2)After creating app registration Copy the client ID and tenant ID, pasting them into _OAUTH_SERVER and _OAUTH_CLIENTID in config.inc. The _OAUTH_SERVER entry should be the login.microsoftonline.com URL but with TENANT_ID replaced with your directory (tenant) ID
3)add a new secret and select the appropriate time. Don’t forget you will need to update this before it expires, so make a note in your calendar. Once done, copy the secret value and paste this into _OAUTH_SECRET within config.inc
4)After that able to browse to your application and be prompted to log in.. On your first go, you’ll be asked to allow permissions for everyone on your tenant (assuming you have the appropriate admin rights).
After registering the azure ,You can refer this code for a post request
eg:
<?php
$appid = "xxx";
$tennantid = "xxx";
$secret = "xxx";
$login_url ="https://login.microsoftonline.com/".$tennantid."/oauth2/v2.0/authorize";
session_start ();
$_SESSION['state']=session_id();
echo '<h2><p>You can Log In with Microsoft</p></h2>';
if ($_GET['action'] == 'login'){
$params = array (
'client_id' =>$appid,
'redirect_uri' =>'https://example/',
'response_type' =>'token',
'response_mode' =>'form_post',
'scope' =>'https://graph.microsoft.com/User.Read',
'state' =>$_SESSION['state']);
header ('Location: '.$login_url.'?'.http_build_query ($params));
}
if (array_key_exists ('access_token', $_POST)){
$_SESSION['t'] = $_POST['access_token'];
$t = $_SESSION['t'];
$ch = curl_init ();
curl_setopt ($ch, CURLOPT_HTTPHEADER, array ('Authorization: Bearer '.$t, 'Conent-type: application/json'));
curl_setopt ($ch, CURLOPT_URL, "https://graph.microsoft.com/v1.0/me/");
curl_setopt ($ch, CURLOPT_RETURNTRANSFER, 1);
$rez = json_decode (curl_exec ($ch), 1);
if (array_key_exists ('error', $rez)){
var_dump ($rez['error']);
die();
}
}
I have worked on web-based rest API but this the first time I am creating Rest API for mobile apps. I am trying to send SMS code to user posted mobile number. SMS code is saved in session with user ip-address.
Next step, user send the SMS code. Rest API compare posted SMS code in the session.
Here is my code for sending SMS and validating SMS code:
//send sms code here
public function actionSendSms(){
$this->response['success'] = false;
$model = $this->loadPostData('step1phone');
$phone = str_replace('+','',Yii::$app->request->post('phone'));
$model->phone = urlencode(preg_replace('/[^\d\+]/', '', $phone));
if(Yii::$app->request->isPost && $model->validate()){
$code = Yii::$app->helper->generateRandomString(4);
Yii::$app->sms->setMessage($code);
$sms = Yii::$app->sms->send($model->phone);
if($sms->status){
$ipAddress = Yii::$app->request->getUserIP();
Yii::$app->session->set('phone-'.$ipAddress, $code);
$this->response['success'] = true;
}else{
$this->response['errorMessage'] = $sms->errorMessage;
}
}else{
$this->response['status'] = 'error';
$this->response['errors'] = $model->getErrors(); //#TODO
}
return $this->response;
}
//sms code validation here
public function actionSendSmsCode()
{
$ipAddress = Yii::$app->request->getUserIP();
\Yii::info('User IP - '.$ipAddress, 'mylog');
$model = $this->loadPostData('step1phoneVerify');
if($model->validate()){
$this->response['status'] = true;
$this->response['data'] = [
'code' => Yii::$app->session->get('phone-'.$ipAddress),
'postValue' => Yii::$app->request->post('phoneVerificationCode'),
];
\Yii::info('code - '.Yii::$app->session->get('phone-'.$ipAddress), 'mylog');
\Yii::info('postValue - '.Yii::$app->request->post('phoneVerificationCode'), 'mylog');
\Yii::info('User IP - '.Yii::$app->request->getUserIP(), 'mylog');
}
else
{
$this->response['status'] = 'error';
$this->response['error'] = $model->getErrors();
$this->response['data'] = [
'code' => Yii::$app->session->get('phone-'.Yii::$app->request->getUserIP()),
'postValue' => Yii::$app->request->post('phoneVerificationCode'),
];
\Yii::info('code - '.Yii::$app->session->get('phone-'.$ipAddress), 'mylog');
\Yii::info('postValue - '.Yii::$app->request->post('phoneVerificationCode'), 'mylog');
\Yii::info('User IP - '.Yii::$app->request->getUserIP(), 'mylog');
}
\Yii::info('Session - '. json_encode(Yii::$app->session) , 'mylog');
//$this->$this->response['session'] = Yii::$app->session->get('phone-'.$ipAddress);
return $this->response;
}
//Model used for validation.
public function validateSmsCode($attribute, $params)
{
$ipAddress = Yii::$app->request->getUserIP();
if(!empty($this->phoneVerificationCode) && $this->phoneVerificationCode != Yii::$app->session->get('phone-'.$ipAddress))
{
$this->addError('phoneVerificationCode', Yii::t('app', 'SMS code doesn`t match.'));
}
}
When I try testing my code from post Rest API service, everything works fine.
But from mobile apps, is never get validate even I post correct SMS code.
When I try to see in my log file." code -" is empty but "User IP -" get ip-address of the user.
Again here if I use post rest API service, in the log file I get the info as excepted. My frontend for my apps is Android.
What I am doing wrong here?
Your mistake that you used IP address as secure and static value which is wrong.
IP address: The user IP address is not unique per user as there are a limited number, so usually multiple user shared same IP, NAT public IP address, read more about NAT but keep in mind user IP is shared and can change and attacker can spoof it.
php session: are data that are usually stored on server (not true in all cases). So the server send a key to the client as secure token, and each time the client with send this token in cookies so the server can load the session. So you don't need the IP you Already have the secure token.
Saving data to session:
Yii::$app->session->set('phone', $model->phone);
Yii::$app->session->set('code', $code);
//Just use key (static string) to store in session as this session in unique per user
reading data from session:
$phone = Yii::$app->session->get('phone');
$code = Yii::$app->session->get('code');
//Just use key that you used to store the data
I advice to read more about Yii2 session YII2 session guide
Keep in mind that you should send session id in all requests using cookies. Also in APP development sessions are rarely used and they usually use rest authorization like auth2 and cache to store data on server.
Session Example: suppose we have this code
public function actionPageCount(){
if(Yii::$app->session->get('count'))
Yii::$app->session->set('count',Yii::$app->session->get('count')+1);
else
Yii::$app->session->set('count',1);
return Yii::$app->session->get('count');
}
First time the user call this action the if statement will be false because the user doesn't have a session id, so in else the web app will create a new session and will set count to 1. When the session is created the server will send to the browser or app this header.
Set-Cookie: PHPSESSID=rl721ac6h3vfgld5repf8pcjl6; path=/; HttpOnly
which mean create new cookie named PHPSESSID with value of rl721ac6h3vfgld5repf8pcjl6. So when the user call the action again. The server will load the session based on the session id. And if the user didn't include the session id the server will create new session. Call this method from a browser and see the behavior then open and new private tab and call it again and see that the server will manage the session for you. In app you have to save the session id and added as cookie in each request.
I am creating a API in Codeigniter.
In this API I have a login function for user. If Login is successful I set user data in CI session and return the session back to user.
Now is it possible that user can use that session id to validate himself for all his other requests like add/update/delete. Basically I want that when the user sends next request I can validate his credentials based on his session id.
Client Request Code :
public function login()
{
$url = 'http://localhost/bizCloudDS/server/login';
$timestamp = gmdate("His");
$parameters = array("reqest"=>"login", "username"=> "admin", "API_AccessKey"=> "b5741564rda4a4d91965d3b5", "GMT_Timestamp"=> $timestamp);
$json = json_encode($parameters);
$encrypted = $this->bizEncrypt($json , 'enc' );
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, 1);
curl_setopt($ch,CURLOPT_POSTFIELDS, $encrypted);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
echo $result;
curl_close($ch);
}
Now above was a sample request from client to server for Login.
On Server Side the server validates the credentials give by the client, if validated returns this json response :
{"ResponseCode":"200","Reason":"Success","Session_ID":"euo1obqeekd5vtb0ult9nj84kii1kqni"}
Now I want that if the user send another request lets say create_user in this he will send the session_id returned from the login request. So how can i fetch the session data by this session id on server side?
Is this good practice ?
you are on wrong way:
I recomand:
Use database and cookie for login (not sessions). OR
You need persistant curl connection (explore CURLOPT_COOKIEJAR) to understand how you login then use same session for other things.
If the user isn't logged directly into your system, but is using a third-party tool via API, then using the session ID doesn't make sense because there actually is no session in the traditional sense. It's a one time call/response.
It seems a better idea to use some sort of request signature to verify that the individual accessing your system is who they say they are and have the access to do what they're trying to do (ie some kind of key hash). For each call, you would authenticate the call itself, not an active session.
Or you can use a persistent cURL connection, but that could be more prone to headache.
I am trying to securely login a user via their Google account.
I am at the stage that I retrieve the userID and oAuthToken using this cordova plugin.
Now I am at the point where I need to send these credentials to my server and then on the server side validate the integrity of the token. Essentially I am trying to perform this part of the process.
I am confused as to which token I should try to verify using the Google client api. Should I use the userID or the oAuthToken ?
The documentation mentions validating the userID but I find this strange. Wouldn't this mean that if anyone gets my user id they can essentially break into my server ? The user id never changes (correct me if I am wrong here) so it seems insecure to validate on this. Wouldn't it make more sense to validate the oAuthToken which is set to expire ? Or does the user ID also expire ?
Any advice would be welcome.
Thanks,
Fido
Edit:
For anyone interested. My confusion arose due to not understanding fully three tokens which the google api can return: userId, oAuthToken, and idToken.
Briefly:The userId is returned with most api calls identifying the user. This appears to be constant. The oAuthToken in my case was returned when I accessed the google api as an Android client. The tokenId is returned when accessing the api as a web client. So those wishing to do server side validation using a mobile retrieved token should access the api as a web client. The token returned can then be validated server side using code similar to the accepted answer below.
you need to validate the IdToken, never send the userId on an open line. the IdToken expires quickly and it is virtually impregnable to brute force impersonation attacks.
this php snippet receives an HTTP request that starts with idtoken=, validates your token serverside and returns either the complete array or user email:
<?php
$inputRaw = file_get_contents('php://input');
$idToken= substr($inputRaw,8);
$fp = fopen('twoStepOutput.txt', 'a');
$url = 'https://www.googleapis.com/oauth2/v3/tokeninfo?id_token='.$idToken;
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
$json = json_decode($response, true);
curl_close($ch);
$userEmail = $json["email"];
$clientId = $json["azp"];
//fwrite($fp, date("YmdHis")."\r\n$idToken\r\n");
fwrite($fp, date("YmdHis")."\r\n");
fwrite($fp, "email Confirmed by GOOGLE:[$userEmail]\r\n");
//print_r($json); // returns array console readable
print_r($clientId); // returns google client id for verification (without transfering user data)
fclose($fp);
?>
just in case you are in doubts, this is what an IdToken looks like:
eypZCI6OiJSUzI1JhbGciNiIsImtIjk4MzQxMzgyMWJmMzhiNTJlM4OTI2YTllMTc0YTc5MWMwNGMifQ.eyJpc3MiOi3VizExYJhY2NvdW50cy5nb29nbGUuY29tIiwicmEIjoiMTAzNDUyNjAwODM5NzY3MjU2MDE0IiwiYXpwIjoiMTA3OTMxMTEyNTc1OS1lYWJhbWV0b2ZldjIwY28zbGQ5b2o1YWQwMzFuZG9nMC5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsImVtYWlsIjoidG9ueWdpbGJyQGdtYWlsLmNvbSIsImF0X2hhc2giOiJaSkhxbUZHcnR5Y29kdEhhOGJvMEYWY1NTk2NzUsImV4cCVBIiwiZW1haWxfdmVyaWZpZWQiOnRydWUsImF1ZCI6IjEwNzkzMTExMjU3NTkt1ldG9mZXYyMGNvM2xkOW9qNWFkMDMxbmRvZzAuYXBwcy5nb29nbGV1c2VyY29udGVudC5jb20iLCJpYXQiOjE0MzZWFiI6MTQzNjU2MzI3NSwibmFtZSI6IlRvbnkgR2lsIiwicGljdHVyZSI6Imh0dHBzOi8vbGg0Lmdvb2dsZXVzZXJjb250ZW50LmNvbS8tQVREckRSbF9UdFEvQUFBQUFBQUFBQUkvQUFBQUFBQUFBRncvOVdDQnZkYlpUTEEvczk2LWMvcGhvdG8uanBnIiwiZ2l2ZW5fbmFtZSI6IlRvbnkiLCJmYW1pbHlfbmFtZSI6IkdpbCIsImxvY2FsZSI6ImVuIn0.L4peW11TD0bDOlvYKNY60ieZ1sbZfW9gEImcuxVA5f9U_4N49Io1CFXoGKmEPR_ij4q38tF2drPMOKijQePwlrxDui37ubzAdVkuksCJUobzjD1_eccF_8GldP5Y1_XsU8xrZeEnfabfiYpr-VwoLzIeNNUdy9SUbUWjMHNcvf4dGFMzE_SONHr57igjHK3rGkbvLo-UduFngm3e-EL0YR2zOKOVj1Qs8g8_qpWgkn8XABTme1thmuU8OfC-HaF9_B2Zk2UCsnOu4ApiYZk3DPIKgeX6AF11kYnzgvciYheWeddly0foT4G00C7w_wgtd-LSRw0XZltec_MPMa2QSA
I am writing a PHP application that's supposed to allow users to add certain events to a private Google Calendar. The calendar is owned by me, and I need a way for PHP to communicate with the calendar API using fixed credentials (everyone can add events using a form on the website, but the calendar itself is not publicly visible).
From what I have read, this is possible using ClientLogin in the v1 API. In the v3 API, however, the available options are OAuth2.0 or the API key. Using the API key doesn't seem to work, since it can only be used for requests that don't require authorization, and OAuth doesn't seem right either, because users are not supposed to access their own calendars, but the one my application uses.
I thought about getting the OAuth token programatically, but that's bound to break sooner or later, since the OAuth dialog can use captchas.
This seems to be such a standard use case — a web application that lets users interact with a single calendar in some predefined ways — yet I can't find any documentation on how to make it happen in the v3 API. Can anyone help me?
I have found a solution that I think that is "the official" for what you want to do.
First, you have to activate a Google API "Client ID for installed applications".
Go to the Google API console and create the project.
Then, activate the calendar.
Go to the "API access" option, and use the "Create OAuth 2.0 client" button.
Give a name (and a logo, if you want) to the product. Click "next".
Choose the "Installed application" option and click "Create Client Id".
Now you have your access configurated. Now, you will need some codes. To obtain them:
*The "Authentication Code". To get it, you need the following information:
SCOPE: https://www.google.com/calendar/feeds/ (if you want to access the calendar API. There are others you can find them at the OAuth 2.0 Playground)
CLIENT_ID: You will find it at the API Access Section at the Google API Console.
REDIRECT_URI: Get it at the same place.
Now, copy the following code into a file, put the values into the variables, execute the code (php -q script_name.php), and go to the URL printed.
<?php
$scope = '';
$client_id = '';
$redirect_uri = '';
$params = array(
'response_type' => 'code',
'client_id' => $client_id,
'redirect_uri' => $redirect_uri,
'scope' => $scope
);
$url = 'https://accounts.google.com/o/oauth2/auth?' . http_build_query($params);
echo $url."\n";
?>
The web page will ask you to allow the access. Do it, and you will get a code, which is your Authentication Code.
*The "Refresh Code". To get it, you will need:
The data you used before, plus the "client secret" code in the API Console, between the "client id" and the "redirect URI".
As you did before, copy the following code, and put the variables in place (the code field is the Authentication Code).
Execute and the result is the "Refresh Token".
<?php
$url = 'https://accounts.google.com/o/oauth2/token';
$post_data = array(
'code' => '',
'client_id' => '',
'client_secret' => '',
'redirect_uri' => '',
'grant_type' => 'authorization_code',
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
$token = json_decode($result);
echo $token->refresh_token . "\n";
?>
At this moment, you have all you need. Be careful if one day you change the Authentication Code. You will have to get new keys.
To access a calendar service, here you have the example:
Change the variable values before using it.
This example gets the primary calendar events, but you can change the address for any in the calendar API (http://code.google.com/intl/ca/apis/calendar/v3/getting_started.html#background_operations)
<?php
$scope = 'https://www.google.com/calendar/feeds/';
$client_id = '';
$client_secret = '';
$redirect_uri = '';
$refresh_token = '';
$token_url = 'https://accounts.google.com/o/oauth2/token';
$post_data = array(
'client_secret' => $client_secret,
'grant_type' => 'refresh_token',
'refresh_token' => $refresh_token,
'client_id' => $client_id
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $token_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
$token_object = json_decode($result);
$access_token = $token_object->access_token;
// Get the results
$rest_url = 'https://www.googleapis.com/calendar/v3/calendars/primary/events';
$header = "Authorization: OAuth " . $access_token;
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, array($header));
curl_setopt($ch, CURLOPT_URL, $rest_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$rest_result = curl_exec($ch);
print_r(json_decode($rest_result));
?>
First, the script asks for an "Access Token", which is valid for an hour. Then, the script gets the REST service (any in the calendar scope), sending the access token in the header.
To give a best speed at the scrip, it would be good to store the access token in a cache until it's older than 3600 seconds. This way, the script would avoid one of the two calls.
Tips:
Visit OAuth 2.0 Playground to understand all the information sent in the OAuth process. It helped me a lot
A post by Eric Nagel in his blog gave me the solution. All the merit is to him. I can't link it since I haven't got enough "reputation".
You will need to use both the Developer Key (API Key) and OAuth2. The developer key authenticates who wrote the software and is used for things like quota which is on a per developer basis not a per user basis. OAuth2 is for user authentication and will be need to access the non-public calendar.
OAuth2 has a renew token from which you can generate a session token and this means that you will not need to screen scrape the OAuth screens to get authenticated. To get this I would write a little command line application, or you use a one off PHP page.
Under the Google Api Console go to API Access
Generate a new Client ID and choose Installed Application ( as you will be authenticating you server as you not as your user)
Either using a console app or a one off PHP page authenticate using OAuth and your google account (the one with the calendar you want access to)
In the return from the authentication there should be a renew token, (called renew or refresh or something similar). Save this string and make it available to your PHP site.
When you need to access the service your OAuth library should have a renew/refresh call. There is an example using .Net below.
private IAuthorizationState CreateAuthorization(NativeApplicationClient arg)
{
// Get the auth URL:
IAuthorizationState state = new AuthorizationState(new[] { AdsenseService.Scopes.AdsenseReadonly.GetStringValue() });
state.Callback = new Uri(NativeApplicationClient.OutOfBandCallbackUrl);
if (refreshToken.IsNotNullOrEmpty()) // refreshToken you stored in step 4
{
try
{
state.RefreshToken = refreshToken;
if (arg.RefreshToken(state)) // This is calling out to the OAuth servers with the refresh token getting back a session token, returns true if successful.
{
if (state.RefreshToken != refreshToken) // if the refresh token has changed, save it.
{
PersistRefreshToken(authorization.RefreshToken);
}
return this.authorization = state; // Retain the authorization state, this is what will authenticate your calls.
}
}
catch (ProtocolException ex) {...}
The AuthorisationState that has now been renewed can then be used to authenticate call you make to the API. this state can be used many time until it expires and then can be refreshed. As you are authenticating your application as yourself not as a user this AuthorisationState can be shared by all you sessions. Both the current AuthorisationState and the refresh token should be kept securely on your server and never sent to the client, if you ever sent these as part of a response your clients would have the same privileges as your code application
Can also be used with the Google php library. The access token for the $client->setAccessToken() function has to be formatted in the following way:
$at= '{"access_token":"' . $access_token . '",' .
'"token_type":"Bearer",' .
'"expires_in":3600,' .
'"refresh_token":"' . $refresh_token . '",',
'"created":' . time() . '}';
Where $access_token is the access token found by you and $refresh_token is the refresh token. Tested with the useless simple.php google example.
Authentication is then just:
$client->setAccessToken($at);