Google OAuth2 - No refresh token / permission to access data while offline - oauth

According to the documentation here:
https://developers.google.com/accounts/docs/OAuth2WebServer#offline
Requests with access_type=offline in the querystring should grant a permission to access data while the user is offline and result in google sending a refresh token when the user accepts. This is no longer happening as of a few days ago. Does anyone know what changed or if there is a better way to go about getting an access/refresh token?

Related

how to use oauth2 token permanently?

I would like to use the oauth2 token permanently in my website.
Using google API, when the user giving permission to manage their google calendar, I am getting the access token from google API. I want to save it in database and use it for the last long.
But it is getting invalid. I tried to refresh the token using the oauth2 refresh token API. But getting the error as follows.
Array ( [error] => invalid_grant [error_description] => Token has been expired or revoked. )
I don't want the user to give the permission each time when he enters the website.
I would also like the admin need to access the user's calendar using this token or any other way if it is.
How can I achieve this?
Instead trying to get the permanent token, I am using the refresh token option.
When I call the google calendar using tag, I have added the parameter like "access_type=offline" as follows
$login_url = 'https://accounts.google.com/o/oauth2/auth?scope=' . urlencode('https://www.googleapis.com/auth/calendar') . '&redirect_uri=' . CLIENT_REDIRECT_URL . '&response_type=code&client_id=' . CLIENT_ID . '&access_type=offline';
After the user allows, I'll get access_token with refresh_token as response. I am saving those in database. Then everytime, when the user's calendar access by the admin, will get the new access_token using the refresh_token that is stored in the database through the refresh_token api call until the user use the unsynchronize option in my site.
Once the user unsynchronized the calendar, I'll update the database.
Problem is resolved.
Bottom line is you can't get a permanent token - but you can mitigate the need for your user to re-supply credentials.
The solution depends what grant type you are using (which depends largely on whether your application runs on a server or or a end-user's machine). You mention a website so hopefully you use a grant type which returns a refresh code too.
If your app runs on a server and you get a token via the authorisation code grant then you should be able to also get a refresh token when you get an access token. You can use that refresh token to request new refresh/access tokens on a back-channel, without need of your user, or their credentials.
Effectively you should then have long-lived access to your user's google resources providing the user doesn't revoke access.
If you use other grant types, like implicit grant, then you can't get a refresh token. You will need to regularly obtain a new access token. If your user remains logged-in to google on the device your app is running on then they should not be required to supply their google credentials when you request a new access token, so you won't be constantly pestering them for credentials.

What does "offline" access in OAuth mean?

What exactly does the word "offline" mean with regard to the offline access granted by an OAuth server?
Does it mean that the resource server will return data about the user even when the user is logged out of the third-party application or when the user is logged out of the OAuth resource server such as Facebook or Google or Twitter?
Offline access is IMO a really bad name for it, and I think its a term only
Google uses its not in the RFC for OAuth as far as I remember.
What is Google offline access?
When you request offline access the Google Authentication server returns a
refresh token. Refresh tokens give your application the ability to
request data on behalf of the user when the user is not present and in front of
your application.
Example of an app needing offline access
Let's say I have a Super Awesome app that downloads your Google Analytics Data,
makes it into a nice PDF file and emails it to you every morning with your
stats. For this to work my application needs to have the ability to access
your Google Analytics data when you are not around, to give me permission to do
that. So Super Awesome app would request offline access and the
authentication server would return a refresh token. With that refresh token
Super awesome app can request a new access token whenever it wants and get your
Google Analytics data.
Example of an app not needing offline access
Let's try Less Awesome app that lets you upload files to Google Drive. Less
Awesome app doesn't need to access your Google drive account when you're not
around. It only needs to access it when you are online. So in theory it
wouldn't need offline access. But in practice it does, it still gets a refresh
token so that it won't have to ask you for permission again (this is where I
think the naming is incorrect).
Helpful quote from the OpenStack documentation:
If a refresh token is present in the authorization code exchange, then it
can be used to obtain new access tokens at any time. This is called
offline access, because the user does not have to be present at the browser
when the application obtains a new access token.
The truth about offline access
The thing is that in a lot of cases the authentication server will return the
refresh token to you no matter what: You don't have to actually ask for anything –
it gives it to you. Giving you the ability to access the users data when they
aren't around. Users don't know that you could access their data without them
being there. It's only the JavaScript library and I think the PHP library
that hide the refresh token from you, but it's there.
Example
By just posting (i.e. HTTP POST request):
https://accounts.google.com/o/oauth2/token?code={AuthCode}&
client_id={ClientId}.apps.googleusercontent.com&client_secret={ClientSecret}&
redirect_uri=urn:ietf:wg:oauth:2.0:oob&grant_type=authorization_code
Here is the response:
{
"access_token": "ya29.1.AADtN_VSBMC2Ga2lhxsTKjVQ_ROco8VbD6h01aj4PcKHLm6qvHbNtn-_BIzXMw",
"token_type": "Bearer",
"expires_in": 3600,
"refresh_token": "1/J-3zPA8XR1o_cXebV9sDKn_f5MTqaFhKFxH-3PUPiJ4"
}
I now have offline access to this users data, and I never told them that I
would have it. More details be found in this short article: Google 3 legged
OAuth2 flow.
Useful reading
Using OAuth 2.0 for Web Server Applications
Understanding Refresh Tokens
By design the access tokens returned by the OAuth flow expire after a period of time (1 hour for Google access tokens), as a safety mechanism. This means that any application that wants to work with a user's data needs the user to have recently gone through the OAuth flow, aka be online. Requesting offline access provides the application a refresh token it can use to generate new access tokens, allowing it to access user data long after the data has gone through the OAuth flow, aka when they are offline.
Getting offline access is needed when your application continues to run when the user isn't present. For instance, if there is some nightly batch process, or if your application responds to external events like push notifications. However if you only access user data while the user is actively using your application then there is no need for offline access. Just send the user through the OAuth flow every time you need n access token, and if they've previously granted access to your application the authorization page will instantly close, making the process nearly invisible to the user.
For Google APIs, you can request offline access by including the parameter access_type=offline in the authorization URL you present to your users. Offline access, and hence refresh tokens, is requested automatically when using the Installed Application flow.

Getting refresh tokens from Google with OAuth.io

I am trying to get access tokens from OAuth.io for any Google based provider however whenever I authenticate I get an access_token but no refresh_token. I have chosen offline for the access_type but still no joy.
I have tried looking through the documentation for a solution but it barely covers anything related to the refresh token.
To get the refresh token from Google, you need 2 things:
The offline option
cf https://developers.google.com/accounts/docs/OAuth2WebServer
"A token that may be used to obtain a new access token. Refresh tokens are valid until the user revokes access. This field is only present if access_type=offline is included in the authorization code request."
The option approval_prompt set to "force"
cf https://developers.google.com/accounts/docs/OAuth2WebServer
"Important: When your application receives a refresh token, it is important to store that refresh token for future use. If your application loses the refresh token, it will have to re-prompt the user for consent before obtaining another refresh token. If you need to re-prompt the user for consent, include the approval_prompt parameter in the authorization code request, and set the value to force."
so your script should look something like
OAuth.popup('google', {
authorize: {
approval_prompt: 'force'
}
}).then(function(google) {
console.log(google.refresh_token)
//send the refresh token to your server
})
If you are working client-side (Javascript / iOS / Android / Phonegap), you may also need to activate the following option: Send refresh token to front-end in the OAuth.io dashboard > General > advanced option to allow your client side SDK to retrieve the refresh token
https://jsfiddle.net/Lqyc5jpw/

What is the Youtube OAuth 2.0 user token validity period?

I read the documentation in the Youtube developers website it does not talk about any validity.
Does the OAuth 2.0 standards define any validity period or is the authorization token valid till the user revokes it manually ?
The OAuth spec defines that the token should expire shortly after its granted, so will it expire after I get the
access and refresh tokens ?
And can I use this access token for all future API requests or do I need to get a new token periodically ?
I'm assuming you are talking about the authorization code, you're mixing the terms a bit here.
From the OAuth 2.0 draft:
The authorization code MUST expire shortly after it is issued to mitigate the risk of leaks. A maximum authorization code lifetime of 10 minutes is RECOMMENDED. The client MUST NOT use the authorization code more than once. If an authorization code is used more than once, the authorization server MUST deny the request and SHOULD revoke (when possible) all tokens previously issued based on that authorization code.
After using it once for getting the access token, you can not use it again. You also don't need to retrieve an authorization code periodically. You do this only when you have no access token for a user, but want to request his data.
Your access token some time expires. You know when by either looking at the expires_in value that got send with it, or by doing a request to the API and getting an access token expired error back. Then you can use the refresh token to get a new access token without the user being involved.
Very useful step-by-step guide about how to get access and fresh tokens and save them for future use using YouTube OAuth API v3.
PHP server-side YouTube V3 OAuth API video upload guide.
The good thing is, you do not need to worry about the expiry of the tokens, as the script in this guide checks, saves, and updates the token in a txt file for future access.
{"access_token":"XXXXXXXXX","token_type":"Bearer", "expires_in":3600, "refresh_token":"XXXXXXX", "created":000000}
We use at http://presentationtube.com and it works fine with thousands of users.

Oauth flow for google

I am trying to impliment Oauth for my webapplication for google.I am worked upon a POC and it working fine but i have a confusion and not sure how best it can be achieved.
I am using scribe java API for Oauth.
here are the steps i am performing.
Getting request token from Google.
Redirecting user to Google to authenticate them self and authorize my serivice to access his/her few details.
get Access Toekn from google by providing request token and verification code given by google.
Accessing user info once google provide Access token.
now my main confusion is at step no 3, since i am working on a web-application so it will be a 2 step process.
Redirecting user to google
Handling back google redirect.
In order to get an Access token i need to provide same request token which i got at step1 else my request being rejected by the user.
The request token contains 2 things
Toekn -->which is based on the registered application so not an issue
Secret-->This is always being a random string so it should be same when asking for access token
that means i need to store this secret either in my session or some where so that i can access this secret when user is being redirected back to my application.
My confusion is,since in order to save it in session i have to create a unique key and some way to access it in the other action class which will handle Google Redirect back how can i achieve this since at a given time so many user can ask to login using google.
any help in this regard will be much appriciated.
Thanks in advance
When you receive the request token + token secret, use the request token as the unique key of your session to store the token information. After the authorization process, in the callback url, you have access to the request token (it's one of the parameters passed to the callback url). Using this parameter as the session key, you can restore the token information from session, including the token secret, and use it to sign your request for changing the request token for access token. After receiving the access token, a new token secret is returned to you and you can delete the old one from session.
how can i achieve this since at a given time so many user can ask to
login using google
This is not of any problem because for every single user on your site, you are given a different request token.

Resources