I have a website in node js and react js. Whenever a user signIn on my website, they recieve a refresh token which is stored in an httpOnly cookie and an access token which is stored in the memory. When the access token expires I sent the refresh token in the request to get a new access token but I cannot understand where to store the refresh token. Should store it in my database because once the httpOnly cookie expires, there will be no way to get that back. So should I store it in the user object or in an array where all the referesh tokens are saved and whenever a request for new access token comes, I find the refresh token in that array and if it exists, I give them new access token.
Please suggest a safe way
It's better to store a refresh token locally. If the database would get hacked, the hacker would have unlimited access to the accounts using the refresh tokens. For more information, check out this post on Stack Overflow
Both access_token and refresh_token is stored on client end. This client end either could be browser or system (invoking the apis). For browser, you can store the refresh token in local storage or in other available options. For external systems, it could be secure storage which can be a database.
Related
I'm using 'dio' interceptor, and when I pass expired access token & refresh token it returns 400 error
Is there any way to handle this not to direct login page and make stay connected and also not to
save credentials in local storage
In my Java/Ionic2 application, I request, through REST services, authentication to Google Drive with the refresh token, and then with access_type=offline, as described here: https://developers.google.com/identity/protocols/OAuth2WebServer#refresh.
The server responds 200 OK, so it gives me a refresh and an access token, only the first time I request access. If I try to redo all the authentication process with an already authorized account, from the same browser, even after logging out, the server response does not give me the refresh token, but only the access token. why? Did anyone have such a problem? Thanks
AFAIK, refresh tokens are only provided on the first authorization from the user. You should only obtain a refresh token if your access token have expired and you need new access tokens. As discussed in token expiration, you must write your code to anticipate the possibility that a granted token might no longer work. That's were you will need a refresh token.
See this SO post for additional insights.
I'm using OAuth as:
a secondary method to sign users into my web application (rather than manually providing their name, email and password)
a way to receive to receive user data throughout the website.
What would be considered best practice when storing access tokens? I have two options:
Store access tokens in cookies
Store access tokens in a database
What are the advantages and disadvantages of either choice?
Regarding token expirations, what should be done to handle this?
One way I know I could handle this is by checking whether there was an error when calling the API and so requesting a new token and then calling the API again. However when requesting a new token, will I require the user to sign back in again? I would imagine this would be a problem when a page on my website requires data from Facebook, but to retrieve it, users have to log back in.
I don't understand how other websites manage to maintain access to Facebook, Google or Twitter APIs without requiring me to log back in again, especially when I'm on another device where I haven't once logged in to Facebook, Twitter or Google. How do they do this? Thanks.
If authentication is done using Google OAuth2.0. Google provides two tokens namely, Access Token and Refresh Token.
Access tokens have limited lifetime for 3600 seconds , but refresh tokens are valid for longer period of time.
Refresh token also expire. Read "Token expiration" section of the Google OAuth2.0 link
One can obtain new access token from refresh token without re-login. ReST api
So, one can have logic implemented to check for time elapsed after access token was generated and take precautionary steps for new access token generation.
Google tokens expire in 3600 seconds, so one can get access token say after every 3500 seconds and update the older access token stored with new one for further use. Also one other way could be, to set refresh token in GoogleCredential which is passed as parameter(httpRequestInitializer) while creating the service of any api.(For example look for Drive.Builder)
If you are not storing refresh token from which access token can be regenerated, you have to authenticate again to get new token.
My extension needs to periodically send some data (in the background) to the the server with auth information about the user from FB. So I obvisouly need to send FB token with the data.
Right now I am opening https://www.facebook.com/dialog/oauth?client_id=<APP_ID>&response_type=token&redirect_uri=http://www.facebook.com/connect/login_success.html in a new tab, then retrivieng a token from a hash (using background page), then storing it in localStorage.
But lets say user closes his browser and opens it after the token expires. How should I retrieve a new one without user doing lots of additional clicks?
I'd suggest you should request long-lived token via your server and store that along with the calculated time of expiration that you can get from token debug API in the local storage. Then you refresh the token before it expires to avoid re-authentication.
My app uses Facebook Javascript SDK authorization on client side, and for authorized user app fetches access token from Facebook API, using facebook cookie with signed request and provided code, and store it into database.
Everything is working fine, but i'm wondering, when I should refresh stored access token? What if user have changes password, and have signed in/connected again.
As I understand, now she has new access token, and app should load it from Facebook. But how I can understand when I should check for a new token? Check on each request with facebook cookie doesn't work, because it's few request per second for each user (event if she didn't change a password). Or maybe i'm doing something wrong?
I mean:
I've authorized user on client side
I've cookie with signed request
Signed request is pretty enough to authorize user on server side (validate user credentials)
I can get access token by calling Facebook API, anytime when user user makes request to my app (because I need a code from signed request). So, i'm doing it when I don't have stored access token or existing access token has expired.
access token just stored in database, and can be used anytime, in different thread, maybe few minutes later (mean we don't have user request and cookie with signed request)
What if stored access token not expired, but invalidated on facebook side? I need to fetch new access token, but cookie has gone at this moment.
Currently I see only one way: store code from signed request into databse, and when we have found that we have invalid access token, try to load it. But i'm note sure that it's proper way, and not so much usable for most cases
You have client token and server token, the client one is short lived (a few hours) and the server one is long lived (60 days).
The token on the client side should not bother you too much since you can get a new one easily as it states in the "Handling Invalid and Expired Access Tokens" guide:
Desktop Web and Mobile Web apps which implement authentication with the Javascript SDK
Calling FB.getLoginStatus() or ensuring status: true is set when you
call FB.init() means that the next time a user lands on your
application and is signed into Facebook, the authResponse object you
are passed as a result of those calls will contain a fresh, valid
access token.
In this case, its simply the act of the user using your application
which implicitly generates a new access token.
The token on the server side, which you persist in the db, can not be as easily reproduced, the user has to be sent to the auth dialog again:
Desktop Web and Mobile Web apps which implement the server-side authentication flow
To obtain a fresh access token in this case you must pass the user
through the full server-side flow again: i.e. obtain a code and
exchange it for a new access token.
However, assuming the user has not de-authorized your application,
when you redirect the user into the OAuth Dialog, the user will not be
prompted to reauthorize your application, and will be immediately
redirected to your redirect_uri. This means that the re-authentication
process can appear transparent to the user.
You can of course send a client token to the server and persist that, but it's pretty pointless since it's short lived.
Another option is to use the new endpoint to extend a valid client token on the server side and then persisting that.
As for "how to know when do get a new token", on the server side when you are making api requests just check the response and see if an error returned and if so what it is (there's a list in the first url I added).
If the token has expired then just send the user to the auth dialog again (you can return some kind of code to the client side and do it from there) and then save the new token to the db.
There's no need to check cookies, those are used in the background but you should not have anything to do with them.
Edit
Don't use the cookies, they should not concern you at any time.
What you should do:
On the server side you should follow the instructions in the Server-Side auth guide, get the "code" and exchange it with a token.
That token will have 60 days.
Use that token, which you store in your db, as needed (other threads, what not) and when you are getting an error back from facebook saying that the token has expires just navigate the user back to the auth dialog page.
You can not use the "code" to get more than one token so that won't help you.
If the user session (and token) got invalidated (for various reasons) you will still get an error back from facebook when trying to make an api request, when that happens just send the user to the auth dialog again.