I follow the steps in the Spotify Web Api Tutorial using the authorization-code from the Spotify Accounts Authentication Examples. Everything is okey, I register an application with Spotify, authenticate a user and get authorization to access user data and when the page show me the user data the refresh token is different each time I authenticate myself. I think refresh token shuld not change.
The only modification I did in the example code was replace the client id, client secret and the redirect uri with the correct values from my application.
Any advices?
For the Authorisation Code Flow you just need to do that initial authentication you're already doing. It will always return a new refresh token however that token can be used over an over with 4. Requesting a refreshed access token; Spotify returns a new access token to your app from Authorisation Guide that will return you a new access token for subsequent calls and you won't need to do the Authentication Step you're doing multiple times just keep doing that one.
Related
Using Java OAuth2 client library: scribe 1.2.0 (https://github.com/scribejava/scribejava)
I am able to get refresh token from the authorization code (i.e; by making POST call to https://accounts.google.com/o/oauth2/token with client_id, client_secret, code, scope, grant_type (authorization_code), redirect_uri parameters). And I have persisted the refresh token in DB.
And we support drive and calendar scopes => so, I do store two refresh token per user (email)
And then clients will be invoking API to get access token (then I am making POST call to https://accounts.google.com/o/oauth2/token with refresh_token, grant_type (refresh_token), client_id and client_secret). And the call is successful. i.e; happy normal path works.
But eventually getting new access token from refresh token is failing with invalid_grant error code (with Bad Request OR Token has been expired or revoked as errors) (like in 2 days or 3 days etc)
Please do note that the refresh token is not revoked or invalidated explicitly by user or code. Password is not changed. Code is not changed. Client ID and secrets didn't change. I am kind of lost.
Questions
Since refresh token supposed to be a long lasting token, why my application is not able to get new access token from refresh token? Its just failing in like in 2 to 3 days - and its happening regularly in stage and production environments.
Is storing two refresh tokens based on scope (drive and calendar) - per user (email) problem (i.e; as soon as second refresh token is issued the previous refresh token expire)? [Shouldn't be the case - I do know there are limitations per user and client, per user for all clients. But, 2 is too low to reach that limit.]
Answer
Finally was able to resolve it, please see the answer below comment(s) - its related to having two refresh tokens of same email for different scopes, and invalidating one of them.
Getting access token from Refresh token - PostMan
Getting refresh token from authorization code - PostMan
Relevent questions: Google token refresh returns "Token has been expired or revoked."
Since couple of days Refresh token has been automatically expired
Changed password
There are serval reasons why your refresh token maybe expiring. The first one we can lockout as the cause is the user changing their password if you are using a gmail scope and the user changes their password this will cause all outstanding refresh tokens to expire.
User revoked access
If the user revokes your access directly though their Google account this will also revoke your refresh token.
Application status.
Now is your application still in testing on Google cloud console? Have you moved it to published has it been though the verification process? If not then your refresh tokens will probably be expiring after about two weeks although the time frame may have changed as this seams to be something that Google has been working on for the last serval months and there is no official word on it.
Refresh access token gives refresh token.
Another cause which actually could be the case, when you refresh the access token does it return a new refresh token. sometimes I will do this. Always check that this is the same refresh token that you use before if note then its a new one and you should store the new one. See next point for more info on why.
Max number of outstanding refresh tokens.
When a user authorizes your application using offline access you are given a refresh token, if the user authorizes your application again you are given another refresh tokens. you can keep doing this up to fifty times and all fifty refresh tokens will continue to work. As soon as you go over the magic number of fifty then the first one that was created will be expired. This is why it is important to ensure that you are always storing the most recent refresh token for a user in your database.
Basically, if your app has multiple refresh tokens for the same user (Gmail) with different scopes, invalidating one of them will invalidate all the tokens.
that turned out to be the issue as we maintain different refresh tokens based on scopes (say drive, calendar, contacts etc)
I am using IBM Mobilefirst platform 8.0 at the moment.
Currently, I am facing a problem:
On my MFP, I have 1 security check to protect 1 adapter.
The flow is that:
login with the security check
can obtain access token (I call it TOKEN_1)
can request resource from adapter
logout
This step, I use the TOKEN_1 to request the resource from adapter and it returns 401 unauthorized (it's correct here)
login with the security check again
can obtain a new access token now (I call it TOKEN_2)
At this time, I can use both TOKEN_1 and TOKEN_2 to request the resource from the adapter and I think that it's not a good thing (just for my case and from my point of view)
I would think that the TOKEN_1 should not be valid anymore but only the TOKEN_2.
So, my question is that there is any way to invalidate forever an access token after we logout with MFP?
Thank you so much in advance.
You can manually clear out the access tokens in the mobile device using the API clearAccessToken.
You can invoke it before or after your logout call. This is to ensure all token related data held in-memory is cleared. This does not clear any token data you have recorded within in your code and stored.
Once you have logged out with WLAuthorizationManager.logout(securitycheck) , the next time you request a protected resource, MFP client SDK always obtains a new token.
We are using spring API security in a spring boot application.
We have implemented two level of security which is page level and also API level. We support both login from our own application and SSO login. we also skiping two apis from authN ( api/login and /api/token)
I have few questions regarding the architecture.
Number 1:
We have our own login which will get input as userName and password for authentication and returns an access token.
How can I add SSO(Single Sign On) to this API?
Number 2:
How to persist the token and how to use the refresh token.
When the user get logged in, I will create an access token and a refresh token. The access token will be sent back to the UI and the refresh token will be in the DB/cache. When the user calls any API from his browser, he will send the access token with the ajax request, the filter validates the token and sends the responce after validating the token in the preAuthN service.
My question is, if the access token supposedly is expired, then how can I generate my new access token using the refresh token?
Solution 1:
once the server receives the access token, validate that and if the access token expired, from the server itself call /api/token to renew acess token and process the reques and send back the responce with the token
Solution 2:
Once the server receives the access token, validate that and if the access token expired, send the acknowledgement to the browser and the browser will handle it somehow to generate a new access token
Or are there any better solutions?
I want to get users' access_token by using Google Drive SDK in JAVA.
I completed to get access_token when user log-in first time. But, I really want to direct-login. I know access_token be expired, so 'refreshToken' can be my solution. But refreshToken is always 'null'. How can I perform direct-login? Many advices welcome.
You need to separate "login" from "access drive". Once your application has an access token for a given user/scope, it can access Drive on behalf of the user. There are two (main) ways your application can obtain an access token.
It can request access which will involve the user being logged in to grant access.
In step 1, it can request "offline" access, in which case it will be given an access token and a refresh token. It can subsequently use the refresh token to request more access tokens without the user being present.
I suspect that you want to do option 2. This is described quite well at https://developers.google.com/accounts/docs/OAuth2WebServer#offline
If you have tried this and you having problems, please paste your code and the http trace so we can look at the problem with you.
I'm implementing a client-server system. The client logs in with username and password and (initially) the server responds with a token that expires in some hours and is used in the rest of services where the authentication is required.
When the token expires, how should I refresh it?
Saving the username/password persistently (ciphered) and calling the login again
Saving some kind of hash of the password?
Any other option?
How should I send the password to the server?
The client apply a hash and the server just stores it and validates hash (and never know the real password)
The client send the raw password through a secure channel and the server validates (lenght,strength,etc) and store a hash?
Any other option?
Check out this link. -> https://developers.hubspot.com/docs/methods/auth/refresh_token
From what I understand, when you first login with the password/username you should get a refresh token back which you save (to be used on refresh), along with the access token. Every so often you make a call to refresh your token to the server, you provide it with the refresh token and your access token and it gives you a new access token and refresh token.
I think the idea is that if someone sees one of your requests they can only impersonate you for a short while. They don't know the refresh token so assuming they don't see your request to refresh that token they would be cut off when you refresh and get a new access token.
I think sending the password through a secure channel would be fine.
Anyone else feel free to correct me here - I'm just trying to help out.