Use OAuth Refresh Token to Obtain New Access Token - Google API - php

My app is simple, it connects to the Google+ API to authenticate the user, and if successful, it retrieves the user's email and then performs a series of operations on a given database based on the email retrieved.
My main issue is that every hour, my access token expires, and I seem not to know how to "refresh" it. I get the following error, which I imagine is expected:
The OAuth 2.0 access token has expired, and a refresh token is not available.
I am currently storing the access token on a database, and I can therefore retrieve if needed. My only question is how do I use that token to gain a new one?

Whoa, it took me significantly longer to figure this out, and the answers out there seemed quite incomplete to me.
Before we start please keep in mind that this answer assumes you are using the latest Google API PHP Library, as of May 26th of 2014.
1 - Make sure the access type your app requests is offline. A refresh_token is not provided otherwise. From Google: This field is only present if access_type=offline is included in the authorization code request.
$gClient->setAccessType('offline');
2 - Upon the first authorization, persist the provided refresh_token for further access. This can be done via cookies, database, etc. I chose to store in on a database:
$tokens = json_decode($gClient->getAccessToken()); /* Get a JSON object */
setRefreshToken($con, $tokens->refresh_token /* Retrieve form JSON object */);
3 - Check if the AccessToken has expired, and request a refreshed token from Google if such is the case.
if ($gClient->isAccessTokenExpired()) {
$refreshToken = getRefreshToken($con, $email);
$gClient->refreshToken($refreshToken);
}
Where getRefreshToken is retrieving the previously stored refresh_token from our database, and then we pass that value to the Client's refreshToken method.
Quick Note: It's key to remember that if you had previously authorized your app, you probably won't see a refresh_token on the response, since it is only provided the first time we call authenticate. Therefore, you can either go to https://www.google.com/settings/security and Revoke Access to your app or you can add the following line when creating the Client object:
$gClient->setApprovalPrompt('force');
From Google: If the value is force, then the user sees a consent page even if they previously gave consent to your application for a given set of scopes. Which in turn ensures that a refresh_token is provided on each authorization.
Full Sample Here: http://pastebin.com/jA9sBNTk

Related

How long does Instagram API access tokens last?

I would like to know how long Instagram API access tokens last? It's not very clear how long they last on their documentation and every PHP package that uses the Instagram API and they all just expect a static access token (along with the client ID and secret) which indicates to me it doesn't change very much.
I am trying to display an Instagram feed on a website, and would like to know if I need to build extra code to periodically check the access token still works or if this is negligible.
https://www.instagram.com/developer/authentication/
Access tokens may expire at any time in the future.
+
Even though our access tokens do not specify an expiration time, your
app should handle the case that either the user revokes access, or
Instagram expires the token after some period of time. If the token is
no longer valid, API responses will contain an
“error_type=OAuthAccessTokenException”. In this case you will need to
re-authenticate the user to obtain a new valid token. In other words:
do not assume your access_token is valid forever.

laravel 5.3 passport and angular storing access tokens

I am authenticating users to consume my own API (so a trusted source). What I am struggling to identify is where is the best place to store the return access_token on the client side? Do I create a cookie, or save the data in localstorage?
Also should I only store the access_token, I should I record the refresh_token? What is the refresh token used for?
It is safer if you only store the access token on the client side even if your refresh token expires after a certain period of time although doing this decreases the possible attack window.
This is one way of doing it (if you want to store access & refresh tokens):
https://stackoverflow.com/a/18392908/5549377
However there is another way of doing it.
In this way, the client will only get the access token and refresh token is completely hidden from the user. But inorder to do this, the access token as well as the refresh token should be stored in the server side. The best place is in the database. This raises the obvious question: security? Well the answer to that is you can always encrypt the data that is being store in the database and secure your database as much as possible.
Create a table (user_token table) that can store the user_id, access token, refresh_token and even the session_id.
In every login check if a record is existing under the user_id in the user_token table. If it does not exist, request the oauth/token and store the access and the refresh token in the user_token table.
After the login is successful, you can write a .run function in your angular to request for the access token for the user. (remember in the user_token table we had a "user_id" column. Hence you can request filter the current logged in user from the Auth::id() function in laravel.
Once the access token is found, the server should return the access token and access token only to the client.
After the client received the access token, you can do a handshake call to the route which is protected under 'middleware' => 'auth:api' by adding the recieved access_token to the header like this :$http.defaults.headers.common.Authorization = 'Bearer ' + data.access_token;. Also after doing that make sure you add the same token to the a rootscope variable like this:$rootScope.accesstoken = data.access_token;
If the handshake call is successful, then you can add valid access token from the rootscope to an angular cookie like this : $cookies.put('access_token', $rootScope.accesstoken);
If the handshake call is not successful, you can request a new token. To request a new token, use a new route that will redirect to a seperate function. This function will fetch the refresh token under the user_id of the current user and request a new access token from the oAuth end point (refer Passport API docs). Once you do this update the record under the user in the 'user_tokens' table and return the new access token to the web client. On the webclient side, store the recieved token in the angular cookie like this: $cookies.put('access_token', $rootScope.accesstoken); and add that same token to the http headers liek this: $http.defaults.headers.common.Authorization = 'Bearer ' + data.access_token;
By the way why did I mention that I should store the token in the angular cookie. Well if you store it only on the rootscope, if the page refreshes, the app will have to request for a token again because whatever the data in the angular rootscope is lost after refresh. But in the angular cookie, it is not. hence this is why I suggested to add to the angular cookie.
Very important:
For every ajax request you make, if the request fails under the code 401 (unauthorized access), you should call a request new token function from angular to Laravel's request new token function. And once it is successful, insert that new token to the http header and the angular cookie as I mentioned.
Note:
The point of the refresh token is to verify that you are the authenticated user for the old access token (let's call the token xxx).
You can use the access token as long as it expires. Once it does you need to tell the server that you cannot been using this access_token xxx and it is expired now, so give me a new token. When you make this request (to give you a new token) the server should know you are the legitimate user of the previous access token, so the server will ask you to prove that you are legitimate. At that time, you can to present the refresh token and prove the server that you are legitimate. This is the use of the refresh token.
So how will the server verify you are legitimate by the refresh token?
initially when you requested the access token, you are given the refresh token so in that case the server will know.
I suggest you read and learn more on OAuth 2.0.
I recently went through some client-side options for token storage so I'll refer you the answer provided in: Where to save a JWT in a browser-based application.
Long story short, both cookies and Web storage are suitable options for storing access tokens and the right choice depends on your exact scenario.
In relation to what you should store, it's usually just the access token mostly because refresh tokens are not typically issued to browser-based applications because they are long-lived credentials meaning the time available for someone trying to steal them is highly increased and the browser storage options all have their deficiencies.
The refresh token is also of particular interest when a client application wants to have access to a protected resourced owned by the end-user even when the user is not interacting with the application; usually referred to as offline access. Most scenarios for browser based applications still imply that the user is online so lack of refresh tokens is not that a big of a deal.

Refresh token in Oauth2.0

I am making an OAuth 2.0 request and it is returning me JSON with refresh_token and access_token, why are there are 2 in OAuth2.0?
Which one is short lived?
What is the purpose of both?
I read this question on SO but that didn'e helped me much, Any help in this regard will be appreciated
Thanks
The access token is what you will use to authenticate your service requests. It generally contains details about the user or is directly mapped to the permissions about the user and the permissions that he has granted.
These tokens are short lived - something like one hour, the actual duration differs per provider.
The refresh tokens on the other hand are used to get a new access token when the one that you have expires. They have a much longer (sometime infinite, until explicitly revoked) lifetime.
Now, let's consider an end to end scenario. Let's say you create an app that does Facebook actions on a user's behalf - post on their timeline etc.
Your app redirects the user to log in to Facebook - you use Facebook SDK for this.
When the user successfully logs in and gives you the required permissions (post on timeline) you get an access token and a refresh token.
Your app can now hit the Facebook API to post on the user's timeline on his behalf with the access token. This token can be used for one hour (or whatever time the access token is valid)
Once the token is about to expire, you can hit a Facebook API to refresh the access token, as this one is about to expire. So, you call into the API with refresh + access tokens.
The API returns a new access token to you - you can use this now till it expires.
PS - This is not how it happens for Facebook actually. This was just a random example to explain how refresh and access tokens differ.
If this makes sense, go back to the question that you have linked. It has some really good answers. :)

Google API Authentication for server

I've been trying to get Google's Calendar API working in a PHP web application, but I'm having a hard time getting authenticated.
What I want to do is to allow users to interact with calendars of a single account known by the server.
Each type of scenario covered in the OAuth 2.0 docs talks about "user consent" which involves a login form and the individual user logging in, but I want the server itself to authenticate directly and obtain an access token for itself.
Is there some part of OAuth or some alternative mechanism I can use to do this?
In order to do this, you must go through the steps for user consent and then copy the access tokens it gives you into the PHP code.
The usual procedure for OAuth is like this:
Send user to authentication page.
User comes back with $_GET['code']
Send $_GET['code'] to OAuth server for a token
Store token in database for the user (or session, if it's very short lived)
But when doing it with a single calendar like this, you modify step 4. Instead, you dump the token to screen and copy it into your PHP file as variables, instead of putting it in the database. Then when you go to pass the access token to the server, you just pass the known, static token rather than a dynamic token from the database / session.
See mathewh's answer here:
How to automate login to Google API to get OAuth 2.0 token to access known user account
The lightbulb for me is when you get the access token you get a refresh_token as well... you use this token to "refresh" your access token once it expires.
There is no way around a manual authorization step the first time.

Should the access token in oAuth be generated every time the user logs in?

I've implemented the oAuth in php (currently for twitter) and as I've read in several tutorials you should store the access token in db for future use. However I don't see how you know if you have the access token stored for a particular user to decide if you should pull it out of the db or regenerate it. Here's a flow describing my question:
First time user signs in:
get request token
send user to provider's authentication page
user returns to callback url with oauth token and oauth verifier
get access token
save access token/user_id/screen_name on db for future use
User returns 10 minutes later:
access token is still in server session vars if user didn't log out. else, repeat process.
User returns 1 month later:
get request token
send user to provider's authentication page
user returns to callback url with oauth token and oauth verifier
( at this point I only have oauth tokens, how can I know if the user has previously logged in with twitter and pull their access token from db? )
if it is the user's first loggin, generate access token.
The main workflow for oAuth is clear, however it is not clear how to handle returning users and which data should be stored or not.
A million thanks!
You should not regenerate token for each access. Generate it only when it's expired. I've build twitter application using OAuth. Here my flow:
when user login, I will check if they have token in DB
1.1. If it's not exists, authenticate them and then store and use the resulting token
1.2. If it's exists, use it.
1.2.1. If twitter doesn't complain, then the token still valid, use it.
1.2.2. If twitter complained, then the token is expired. Return to 1.1.
1.2.3. If after x retry twitter still complained. Something wrong, notify admin!
Here's the graphical explanation:
The only thing I believe is missing here, is generate a random (long and unguessable) user id first time the user joins the system, and store it forever. this way you can tell who's taking the actions

Categories