I want to add to the token's payload a specific attribute. This attribute can be changed rarely (once per month), however I would like that the tokens would be updated immediately after this change.
WORKFLOW
In web/mobile app, user opens a profile view and changes attribute X. The current value of this attribute is also stored in ID token. So when user submit edits, the new value of X should be saved on the backend and should replace the old value in ID token. It is important, because attribute X determines whether user can or cannot do specific things in app.
What does Cognito do when payload's attribute change? It sends new version of JWT ID token in the next request?
Should I use refresh token? Or force to sign-out and sign-in user?
Refresh token will be more appropriate in this usecase. Currently, refresh token flow is not exposed in the high level android SDK for user pools because it is done behind the scene by the SDK. For now, you might have to call the refresh token from low level SDK to get around this.
(I am a developer from Amazon Cognito team, we will take this as a feature request to allow this from our high level SDKs.)
Related
Background:
I have a requirement where I need to allow the refresh token live for a really long time for some types of user, but I want to limit it (expire it) for other users.
Both sets of users have to be in the same Cognito user-pool.
My first thought was to check how long the users have been logged-in if they are the type of user I want to limit and call global sign-out to force those users to re-authenticate, but I cannot find any API that will tell me how long a user has been logged in.
As an important side note, since I am using Cognito with Amplify + Appsync, the refresh token is used to obtain new session tokens until the refresh token expires.
Question:
Is there a way in Amplify or Cognito APIs to find out how a user has been logged in in that particular device?
Cognito has a feature that remembers the user's device and records the date in which the device was last authenticated.
Ref: https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-device-tracking.html
https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_GetDevice.html
I am trying to check if the user still exists when Refreshing the Token, returning the user's updated detail (if updated) upon refreshing a token. Is there anyway to retrieve the user's details from the refresh token? [request.user] is currently marked as AnonymousUser so I am unable to know who the refresh token belongs to.
I think it is a good practice to have one endpoint to one type of job. In your case, it will be good to have:
endpoint for a token refresh,
endpoint to get user details.
Please take a look at Djoser package. It has predefined views and URLs that you can reuse.
If you really want to get some user info on refresh, then you can try to put some user's information in jwt payload part. But I would rather go with to separate endpoints. If user will not exists, then refreshing the token won't return new token.
I have a question regarding Amazon Cognito.
What I want to achieve is to set default custom attribute for the user record.
Ideally it will be great if I could set it by default in user pool, for example "custom:domain": "some name". But I can't find an example for this, or maybe set it up in Pre sign-up trigger with Lambda, but I didn't find examples for it also. What I did, when user authenticate I get the user attributes and set the required one with updateAttributes (I use amazon-cognito-identity-js). The downside of this approach that I faced, on first user login he gets the tokens first and only after that this custom attribute it set. So in first login this attribute is missed in token. What I want to ask what is the best approach of doing this kind of staff? And if my variant is appropriate, how could I update user token after changing the user attributes, so they appear in that token.
You will get the new attributes in the tokens on token refresh. However, the SDK's do not provide a method to manually refresh the tokens. We will consider this as a feature request for our SDK's.
Tokens are typically valid for an hour and are automatically refreshed by the SDK when they have expired. So your user's would get tokens with new attributes at-least after an hour.
Another option would be to add a Pre token generation trigger that checks to see if the value is set, and if it isn't overrides it. http://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html#aws-lambda-triggers-pre-token-generation-example-1 It would be set the first time the user gets the token if done this way.
We are integrating on our application the Office 365 functionality throught MSGraph rest api and we are currently getting trouble with the validation of Refresh Tokens, this is the response error code from the server on a invalid petition:
"error":"invalid_grant","error_description":"AADSTS70002: Error
validating credentials. AADSTS70008: The refresh token has expired
due to inactivity.??The token was issued on
2016-04-27T11:44:49.4826901Z and was inactive for 14.00:00:00.
This is annoying because we need the users to aquire their credentials again logging in on Microsoft servers.
Is there any option to avoid Refresh token being invalidated due to inactivity? Or to make longer this expiration?
Refresh tokens have a finite lifetime. If a new token (and refresh token) isn't requested before that time they will expire. Once this happens the user must re-authenticate.
If you need to have perpetual access to the account, you will need to manually refresh the token periodically. You may want to look at this article. It covers the basics of how v2 Endpoint works (and the various token lifetimes).
In most of my implementations I use a queue to handling refreshing tokens. I queue each token to be refreshed at 10 days. If it fails I resubmit to the queue. If it is still failing at day 12 I email the user to inform them there was an issue and they will need to re-authenticate.
UPDATE
Refresh token lifetime was recently changed to until-revoked. You can read about the change here
This is general OAuth (not AAD-specific): obtaining an access token is a 2-step process. The first step is to obtain an auth code which requires the user to authenticate. The second step is to redeem an access token and a refresh token from the auth code. This second step is purely programmatic, i.e. the user need not be present. The app can keep repeating the second step, i.e. redeeming a new access token and a new refresh token from the latest refresh token without the user even know about it.
Your app should schedule frequent 'refreshes' of the refresh token. You can do this at any time while the app is running.
If the user doesn't use the app for an extended period of time, like about 2 weeks (I believe), the refresh token would naturally expire. If you want to avoid that, you'll have to schedule a dedicated job to refresh the token.
Zlatko
I'm planning out adding Facebook integration to a web app I'm working on. For the most part, it's proceeding smoothly, but I am confused on the proper way to handle the OAuth token.
The sequence of events presented by Facebook here is:
Ask the user to authorize your application, which sends them to a Facebook window.
This will return an Authorization Code generated by Facebook
You then hit https://graph.facebook.com/oauth/access_token with your Authorization Code, which will give you a time-limited OAuth token.
Using the OAuth token, you can make requests to access the user's Facebook profile.
Facebook's documentation has the following to say about token expiration:
In addition to the access token (the access_token parameter), the response contains the number of seconds until the token expires (the expires parameter). Once the token expires, you will need to re-run the steps above to generate a new code and access_token, although if the user has already authorized your app, they will not be prompted to do so again. If your app needs an access token with an infinite expiry time (perhaps to take actions on the user's behalf after they are not using your app), you can request the offline_access permission.
When they say to re-run the steps above, what steps need to be re-run to get a new OAuth token? What data (Facebook UID, Authorization Code, OAuth token) does it make sense to save to my local database?
I would like to be able to have the user continue to interact with my site, and in response to certain user actions, I would like to be able to prompt to user if they want to post something to their Facebook wall.
The access token is time and session based and is unnecessary data to store and have no use after the user have closed the session.
The facebook uid is the only thing you need to identify the user.
Since the Facebook API sometimes is horrible slow you could store the username aswell.
But for identification, all you need is the uid.
The documentation that facebook provides has been updated since you asked this question. https://developers.facebook.com/docs/authentication/.