Amplify-js: cognito.user.signOut() does not invalidate tokens

Created on 12 Jun 2019  Â·  79Comments  Â·  Source: aws-amplify/amplify-js

Describe the bug
On calling state.cognito.user.signOut(), session tokens are just removed localstorage.
The actual access tokens and refresh tokens are still valid for the lifecycle of the token.

Expected behavior
This is a security issue. Best practice dictates session tokens should be invalidated server side on a logout request not just deleted on the client. (OWASP session management)

Source Code found here
https://github.com/aws-amplify/amplify-js/blob/68a5ad2fe2b1d9f03cce80d1bf449e454b621760/packages/aws-amplify-react/src/Auth/SignOut.jsx

Cognito Service Team feature-request

Most helpful comment

We are all waiting for it to be fixed.

All 79 comments

@jiachen247 Cognito issues short lived bearer access tokens (valid up to 1 hour). The access tokens are short lived (up to 1 hour) and Cognito has GlobalSignOut Api to invalidate all tokens issued in past. If you are using the cognito-identity-js sdk directly, then the globalSignOut method will invalidate all sessions (see use case #15 here: https://github.com/aws-amplify/amplify-js/tree/master/packages/amazon-cognito-identity-js). This i believe is what you are looking for to invalidate the server side. The user logout is specifically there as to not invalidate other sessions and just sign out the current local user.

cognitoUser.globalSignOut(callback);

@mlabieniec Thanks for your response! yes and no actually. Its closer but its still different. Global sign out invalidates all open sessions. For example, lets say I log into the webapp and a mobile app both use Cognito for authentication at the same time. On global signout, both will get logged out. However, signout should just invalidate that particular session on the client side as well as the server side and not touch the other open sessions. That makes the most sense on reading the docs for the function is intended for.

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

I could not agree more with @jiachen247. I have the same situation of mobile and app usage and the session should be invalidated for each one separately. What actually concerns me more is the fact that I can still use the token after using the "signOut" method of @aws-amplify/auth.

Yes, i am facing the same issue. I am using Auth.SignOut({global: ture}) and it is kicking user to login page of that particuler window. If i open the app in another tab in the same window / access the app from other browser or machine they still find a valid user object from id token. I can still get hold of the application.

I am looking for a solution where if i logout from other tab and come back to another tab and do any operation, it should kick me back to login page.

Any workaround solution for this?

Is there some API endpoint we can hit to invalidate a single Refresh token? Auth.signOut({ global: true }) revokes all refresh tokens, and Auth.signOut() revokes no refresh tokens...

There must be some middleground available....

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

We are all waiting for it to be fixed.

Any news on this? It seems ridiculous that you can't invalidate a single set of tokens on the back end.

any updates from?

Is there someone to actually answer these issues/questions? Too frequently I see only tags added and more people writing they have the same problem. No actual support whatsoever and that's sad.

I also need the ability to:

  • sign out a single user session (only this one with which the sign out is requested) followed by the token invalidation
  • get information (an event?) that the session was invalidated (for example with a global sign out), so I could send the user back to the login screen, as the token is not usable nevertheless, but all Amplify functions don't seem to care, just throw errors.

We encountered the same problem with the AWS Cognito PHP SDK. It seems the documentation is clear for the AdminUserGlobalSignOut function :

Signs out users from all devices, as an administrator. It also invalidates all refresh tokens issued to a user. The user's current access and Id tokens remain valid until their expiry. Access and Id tokens expire one hour after they are issued.

https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_AdminUserGlobalSignOut.html

A much-needed feature would be to invalidate all tokens on AdminUserGlobalSignOut. Our use case : a user password as been changed by an admin or user, thus the user should be logged out automatically. By the documentation, the user would only be disconnected one hour after...

A much-needed feature would be to invalidate all tokens on AdminUserGlobalSignOut. Our use case : a user password as been changed by an admin or user, thus the user should be logged out automatically. By the documentation, the user would only be disconnected one hour after...

By their nature, there is no mechanism to invalidate an access or id token.

The likely solution for your scenario is to track any revoke token events in your app. Then, as part of your token validation process, you can check to see if you've revoked that specific token and if so not authorize the request. You could maintain a database table of revoked tokens, cache the values for performance and have a hygiene process to remove expired, revoked tokens.

Your use-case / scenario is different from the original issue.

By their nature, there is no mechanism to invalidate an access or id token.

That's my understanding of JWTs as well. However, I've seen evidence that Cognito tracks individual access tokens.

If you do a global signout, but save your JWT tokens, and then try to hit another Cognito endpoint (like "global signout" again), you'll get a 400 with the message Access Token has been revoked. This suggests that Cognito is in fact tracking revocation of individual access tokens in some way.

If you do a global signout, but save your JWT tokens, and then try to hit another Cognito endpoint (like "global signout" again), you'll get a 400 with the message Access Token has been revoked. This suggests that Cognito is in fact tracking revocation of individual access tokens in some way.

I thought that when you do Global Signout, secret key(or private key and with that also public key) is changed and every token that was created before calling Signout is invalid. That would mean that validation of each issued token fails. But only thing that is invalid is refresh token. Access token and ID token remain valid until their expiration. More here:
https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityServiceProvider.html

Beside that, there is no way to invalid token. You can only wait for token to expire and become invalid. There is a way to track by yourself which tokens should be revoked(after user logout put that token in database) and to check every time if token that is being used currently is in that database(that means it's invalid) or not(it is valid). But by doing this, you are loosing tokens stateless feature. More about this you can find here(maybe best approach gave Ashtonian):
https://stackoverflow.com/questions/21978658/invalidating-json-web-tokens

This is the best way to deal with everything in Cognito:
https://dzone.com/articles/aws-cognito-user-pool-access-token-invalidation-1

Facing the same issue with cognito-identity for JS. user.signout() just removes the token from local storage. Anyone who had preserved the id token can still connect to the API gateway with it. Any updates or resolution around this ?

Facing the same issue with cognito-identity for JS. user.signout() just removes the token from local storage. Anyone who had preserved the id token can still connect to the API gateway with it. Any updates or resolution around this ?

Only way(for now) that is verified from AWS technical support team is explained here:
https://dzone.com/articles/aws-cognito-user-pool-access-token-invalidation-1

So, idea is to user CognitoIdentityServiceProvider. More about all its methods here: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/CognitoIdentityServiceProvider.html

CognitoIdentityServiceProvider.globalSingOutUser(accessToken) revokes access token
CognitoIdentityServiceProvider.getUser(accessToken) either return error if token is revoked or users data if token is valid(not expired or revoked)

So, in your case, each time when user sings out(logs out) from application, you should call this globalSingOutUser(accessToken) method. And in case you want to check if user is singed out or not(if token is revoked or not) you should be checking also access token using this getUser(accessToken) method. That should be done before calling API Gateway. And if you are worried about someone calling API Gateway with just ID token, you can add this check inside for example Lambda(if API Gateway is calling Lambda afterwards). I don't know whole scenario that you are facing with, but you can find some workaround with this.

Thanks @maros96 for the detailed explanation.

However, when I tried using accessToken as the Authorisation header to connect with API gateway, my API call failed with 401 -Unauthorised. The same call works fine while sending idToken in the Authorisation header. The AWS doc here says we can use either of idToken or accessToken. Is that correct. Can you suggest any cause for this behaviour.

Thanks @maros96 for the detailed explanation.

However, when I tried using accessToken as the Authorisation header to connect with API gateway, my API call failed with 401 -Unauthorised. The same call works fine while sending idToken in the Authorisation header. The AWS doc here says we can use either of idToken or accessToken. Is that correct. Can you suggest any cause for this behaviour.

Yes, thing is that Authorizer can depend on ID Token OR Access Token, but implementation of Authorizer is not the same for those 2 cases. You've created your authorizer to use ID Token. If you want to change it to use Access Token, you have to change firs implementation of authorizer and then put accessToken in Authorization header. That is why you get Unauthorized when you pass accessToken - Authorizer expects ID Token instead. On that link you've sent, on the end, you have links for doing everything in steps(obtain permissions, first create Cognito User Pool, ...) and you should read Integrate a REST API with an Amazon Cognito User Pool.

So, you can try to implement Authorizer to use Access Token(I've never done that and I am not 100% sure that in case that Access Token is revoked, authorizer will return Unauthorized or will let you use your API, but you should try that). You can try that and after testing that, put a comment here for everyone else, including me, to see how does that work :)

In case you don't manage to do that, you can still use ID Token for authorizer and call CognitoIdentitiServiceProvider.getUser(accessToken) after calling API Gateway and before doing everything else. Put that check between API Gateway and rest of your application. For example, as I suggested in previous comment, if you call Lambda from your API Gateway, you can first do this check in Lambda and in case access token is revoked, return error status with message "Access Token is revoked". Otherwise you just continue with Lambda execution(which means that access token is valid).

One more thing, in case access token is invalid in any sense(expired, wrong token use, revoked, signature is not the same as decode(hash(header.payload), publicKey) - which means that someone has change something inside that token), this getUser(accessToken) method will return error. If token is valid, it will return some user data. So, you are not just checking if token is revoked, you are also checking whole validity of Access Token.

We still need a way to invalidate an individual refresh token. I don't want to use Global Sign Out because a user might want to be signed in on multiple devices but just want to sign out of one specific device. It would be a poor user experience.

The current system relies solely on each device just "forgetting" the refresh token if a user logs out on that device. This is not a very secure or reliable way to discard refresh tokens because the tokens themselves remain usable. If you do the forgetting wrong, then the user stays logged in without realizing it. API calls using the "logged out" session still return 200, and so forth.

There isn't any way to invalidate any token(their purpose is to be stateless and to be valid until they expire). There is either a way (1) to revoke all tokens that are valid and not revoked at that time for one user or (2) to track everything by yourself. Which would mean that you should have a database or any storage system to store tokens that are "invalid"(they are valid but you want them not to be) and then when user uses some token, to check in that database if token is there(it acts as invalid token) or not(acts as valid token). This way would give you what you are asking for.
You have that well described in stackoverflow Invalidate JSON Web Tokens debate. Link is in my first comment here.
And regarding AWS, currently only way is to use CognitoIdentityServiceProvider and globalSignOut method. As I've understood, they are working on improving this, but for now it is like that. Once again, you can get what you want by storing tokens somewhere and checking each token if it is in there or not. But then tokens lose their stateless feature and become dependent on storage state.

I am keeping this thread alive because it is AWS's job to implement this. They are the only ones who can implement a true invalidation measure for refresh tokens because it is possible to call the token refresh API directly if you know the user pool and client id (and client secret if needed). Global sign out is a poor user experience, period. It is a copout to say we should use it as a workaround indefinitely and keep inconveniencing users. It would be dead simple for AWS to put invalidated refresh tokens in a DB belonging to each user pool and check against it for each token refresh request. They just do not care enough to implement it. I first opened a ticket about this more than 2 years ago. All it takes is one general XSS attack script aiming at refresh tokens to gain renewable user sessions for many/most Cognito users, lasting between 1 day and 10 years. Sounds lucrative to me. Only those who keep their user pool etc. totally secret are safe, but you have to have your own API wrapper around login etc. to do that.

Thank you to everyone with the feedback and concerns presented in this issue. I apologize that we have not made comments on this issue and I do want to state that we are working internally with the AWS Cognito team on this specific issue. Once we have an update from Cognito regarding this issue, we will provide one. Again, thank you for your concern and feedback.

@sammartinez Great! When can we expect the update?

This is a much needed fix. Please provide a fix at the earliest

In case you don't manage to do that, you can still use ID Token for authorizer and call CognitoIdentitiServiceProvider.getUser(accessToken) after calling API Gateway and before doing everything else. Put that check between API Gateway and rest of your application. For example, as I suggested in previous comment, if you call Lambda from your API Gateway, you can first do this check in Lambda and in case access token is revoked, return error status with message "Access Token is revoked". Otherwise you just continue with Lambda execution(which means that access token is valid).

@maros96 here you say, you can still use ID token for authorizer, but the link that you attached says that

User hits API Gateway with Authorization header (Access token - JWT)

May be I didn't get the idea behind this approach. Can you try to elaborate it a bit. Many thanks.

In case you don't manage to do that, you can still use ID Token for authorizer and call CognitoIdentitiServiceProvider.getUser(accessToken) after calling API Gateway and before doing everything else. Put that check between API Gateway and rest of your application. For example, as I suggested in previous comment, if you call Lambda from your API Gateway, you can first do this check in Lambda and in case access token is revoked, return error status with message "Access Token is revoked". Otherwise you just continue with Lambda execution(which means that access token is valid).

@maros96 here you say, you can still use ID token for authorizer, but the link that you attached says that

User hits API Gateway with Authorization header (Access token - JWT)

May be I didn't get the idea behind this approach. Can you try to elaborate it a bit. Many thanks.

Yes, thing is that you can configure your API Gateway Authorizer to work with either ID Token or Access Token. Depends on your needs.
I wrote that in some previous comment, it starts with: "Yes, thing is that Authorizer can depend on ID Token OR Access Token, but implementation of Authorizer is not the same for those 2 cases. ".
I suggest you to read the AWS documentation(especially for this case) and all comments here and maybe watch some youtube video to clarify everything :) of course, if something else remains non clarified, just ask

+1 on this one. The token lives only one hour, but immediate invalidation would be the clean way to go @sammartinez

@sammartinez Any updates on this issue?

+1 waiting for some news as well

+1 waiting for some news as well

+1

+1

+1

Waiting on this as well

Waiting

By their nature, there is no mechanism to invalidate an access or id token.

That's my understanding of JWTs as well. However, I've seen evidence that Cognito tracks individual access tokens.

If you do a global signout, but save your JWT tokens, and then try to hit another Cognito endpoint (like "global signout" again), you'll get a 400 with the message Access Token has been revoked. This suggests that Cognito is in fact tracking revocation of individual access tokens in some way.

This is not correct, after global signout, if you send the idToken to an API using Cognito authorizer, the request is still valid.

This is correct, JWT tokens are signed and this check is valid until they have expired. Invalidation means an out of band disabling of a token before the expiration time has passed even with a valid signature. This feature is not available in Cognito today however we have passed this request to the service team and they are evaluating it in their roadmap. I'll mark this issue as a Feature Request for the time being.

I wrote an article approaching this, so if someone has reached this page, the article may help.

https://medium.com/javascript-in-plain-english/serverless-things-i-wish-i-had-known-before-i-started-part-1-aws-cognito-cf5d3a0c3d9d

@dmjesus89 How does it relate to this issue?

Looking for updates here as well. It looks like the Global Sign Out is not an option, because the id and access tokens are still valid for an hour after they were created per aws' global sign out documentation.

Signs out users from all devices. It also invalidates all refresh tokens issued to a user. The user's current access and Id tokens remain valid until their expiry. Access and Id tokens expire one hour after they are issued.

Waiting this feature + 1

Waiting this feature + 1

I'm using the user pools hosted ui for oauth flow when integrating 3rd party apps. Even the logout endpoint won't invalidate the current access tokens.

+1 for this feature.

+1 waiting

@sammartinez any update?

Any update on this? Or do you guys have any workaround? Thanks.

+1, it is unbelievable that such a critical feature is still not available, even though it's now been raised publicly almost a year ago, and received a significant amount of interest from your customers.

@undefobj any update, or is there a workaround? I do not think its acceptable to force my users to globally sign out of all apps!

Tokens should be invalidated once they are known to be unused.

A user authenticates against my user pool across multiple devices: browsers, mobile phones, public terminals. They get a separate Refresh Token for each device. If they manually click "log out" on one of those devices, the user will drop its reference to the refresh token. The token will be unused.

If an attacker manages to sniff the refresh token from a public machine, our users should be able to click "Log Out" manually to mitigate having their token compromised.

There is a workaround to do this today: It's to use the signOut({ global: true }) option. This will revoke ALL refresh tokens for the user. This accomplishes the security goals of revoking the unused token, but it simultaneous logs the user out across all devices.

Developers using Cognito are forced to choose between good security and good user experience here.

Is there some reason Cognito is unable to revoke a single refresh token? It sounds like adding a new API to revoke a token could solve this problem, backwards compatibly. I can only imagine there must be some blocking issue in Cognito's end. Perhaps token lifetime for Cognito is handled by some other upstream project that does not give visibility into individual tokens?

A related issue (see the closed issue above, I was referred here), if I remove a user from a user group, the JWT they have is still valid and showing that they are a member of that group. As a result, Amplify/AppSync continue to give them access to data and operations that they should not. I need some way to invalidate the JWT server side.

Waiting this issue to be resolved.
AWS API needs to be have a single token revoked instead of forcing the global sign out for all the tokens.

Just came to this problem and I can't find a solution.

Still waiting ...

Subscribing to this issue as well... There must be a way to invalidate a single token on sign out...

Any idea of "When" ?

I think we need to hit up the Product team about this issue, we’re not
getting a response here. Anyone know of who that would be?

On Fri, Jun 26, 2020 at 10:29 AM Carlos notifications@github.com wrote:

Still waiting

—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub
https://github.com/aws-amplify/amplify-js/issues/3435#issuecomment-650272239,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/AARM2IUWCCBQJQDH5OQSEDTRYTEHLANCNFSM4HXHDUYQ
.

I guess I wouldn't hold my breath. Cognito could put a band-aid on this by storing a unique identifier for each token that was 'invalidated'. It would be slightly antithetical to do with JWT as they are designed so that there is no need to have a database filled with sessions. Sessions sound like what you want, you will have full control over whether they are valid or not. There are plenty of solutions for sessions that are well used and tested. I suggest using one of them.

Related: http://cryto.net/~joepie91/blog/2016/06/13/stop-using-jwt-for-sessions/
Also, sorry, that site really is HTTP only.

Just a quick thought of workaround of this, if we write the same logic of sign-in with sign-out, the difference is sign-out doesn't return access token, refresh token, and id token.
When you sign-in again, the old token will invalid ( that's the same meaning of sign-out )

Any thoughts about this?

I would plan 100% drop off AWS Cognito in the near future of my application.
Still need to figure out putting together better identify solutions

A reply from AWS Technical Support.

Hello,

Thank you for contacting AWS Premium Support. I am Ayushi and I will be assisting you today.

I understand you want to know if we are aware of the  issue that`globalSignOut()` or`signOut()` does not immediately invalidate the token of the Cognito user. Therefore, the user would still be able to access the protected resources using existing tokens. Please correct me if I misunderstood.

From the documentation[1] of the `globalSignOut()`, "This method signs out users from all devices. It also invalidates all refresh tokens issued to a user. The user's current access and Id tokens remain valid until their expiry. Access and Id tokens expire one hour after they are issued". 

As the documentation clearly states that after the token is invalidated, the current tokens are still be valid for 1 hour from the time the tokens are issued. This means that When you perform signOut() or `globalSignOut()`, it just clears the tokens from local cache. However, if the tokens stored somewhere else, it is possible that you could still access the protected resources using the tokens until the current token expires. ie, after 60 minutes of token issue time. I understand this causes some issues such as user would still be able to access the protected resources after they are logged out. Unfortunately, at this moment there are no potential workarounds available to get around this behavior.

As one of our member from service team commented on the issue[2], Cognito service team is working on this feature internally. I understand that the lack of the feature is causing inconvenience. I have added your voice to it along with the rest of our customers that are being actively requesting on this. Please be assured that the service team will take the feedback seriously and work towards improving the Cognito service for better customer experience. However, I will not be able to provide any ETA at this moment as a support engineer, I do not have visibility into service team priorities. Meanwhile, You could keep an eye on our what's new blog [3] for information regarding new feature releases.

Please feel free to reach out to us if you have further queries and I'll be happy to assist you on the same.

References
-------------
[1] https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_GlobalSignOut.html

[2] https://github.com/aws-amplify/amplify-js/issues/3435#issuecomment-578206493

[3] https://aws.amazon.com/new/

A reply from AWS Technical Support.

Hello,

Thank you for contacting AWS Premium Support. I am Ayushi and I will be assisting you today.

I understand you want to know if we are aware of the  issue that`globalSignOut()` or`signOut()` does not immediately invalidate the token of the Cognito user. Therefore, the user would still be able to access the protected resources using existing tokens. Please correct me if I misunderstood.

From the documentation[1] of the `globalSignOut()`, "This method signs out users from all devices. It also invalidates all refresh tokens issued to a user. The user's current access and Id tokens remain valid until their expiry. Access and Id tokens expire one hour after they are issued". 

As the documentation clearly states that after the token is invalidated, the current tokens are still be valid for 1 hour from the time the tokens are issued. This means that When you perform signOut() or `globalSignOut()`, it just clears the tokens from local cache. However, if the tokens stored somewhere else, it is possible that you could still access the protected resources using the tokens until the current token expires. ie, after 60 minutes of token issue time. I understand this causes some issues such as user would still be able to access the protected resources after they are logged out. Unfortunately, at this moment there are no potential workarounds available to get around this behavior.

As one of our member from service team commented on the issue[2], Cognito service team is working on this feature internally. I understand that the lack of the feature is causing inconvenience. I have added your voice to it along with the rest of our customers that are being actively requesting on this. Please be assured that the service team will take the feedback seriously and work towards improving the Cognito service for better customer experience. However, I will not be able to provide any ETA at this moment as a support engineer, I do not have visibility into service team priorities. Meanwhile, You could keep an eye on our what's new blog [3] for information regarding new feature releases.

Please feel free to reach out to us if you have further queries and I'll be happy to assist you on the same.

References
-------------
[1] https://docs.aws.amazon.com/cognito-user-identity-pools/latest/APIReference/API_GlobalSignOut.html

[2] https://github.com/aws-amplify/amplify-js/issues/3435#issuecomment-578206493

[3] https://aws.amazon.com/new/

In that case this thread needs to be closed to stop the spam since it's now been verified that's it's being worked on internally. That work will be prioritized accordingly as you don't know if there's something more important that needs to be worked on first. You can still use cognito and it doesn't break anything so it's not that big of an issue.

In that case this thread needs to be closed to stop the spam since it's now been verified that's it's being worked on internally.

This repo uses a stale bot to close issues. So, if we stop bumping the issue, it gets closed. I'd rather see the issue stay open personally, but I am not a maintainer.

@owenashurst
Statements about the Cognito team working on issues are also no guarantee that the issue will be resolved in any sort of timeframe, or at all.
There are _many many_ basic features that aren't supported in Cognito (Removing custom attributes, password expiry etc) - that have "Been raised to the Cognito team and are being worked on internally" that are still undelivered after 4 years of disappointment. Some of them are fundamental security items (like logging out properly)
Based on previous experience - you don't keep this issue open - don't expect it to ever be done.

Fair enough

On Tue, 30 Jun 2020, 01:48 colinfindlay-nz, notifications@github.com
wrote:

@owenashurst https://github.com/owenashurst
Statements about the Cognito team working on issues are also no guarantee
that the issue will be resolved in any sort of timeframe, or at all.
There are many many basic features that aren't supported in Cognito
(Removing custom attributes, password expiry etc) - that have "Been raised
to the Cognito team and are being worked on internally" that are still
undelivered after 4 years of disappointment. Some of them are fundamental
security items (like logging out properly)
Based on previous experience - you don't keep this issue open - don't
expect it to ever be done.

—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
https://github.com/aws-amplify/amplify-js/issues/3435#issuecomment-651448377,
or unsubscribe
https://github.com/notifications/unsubscribe-auth/ABBTB3HC6D2F3AG6I275VLLRZEY6LANCNFSM4HXHDUYQ
.

What do you think about this workaround? - https://forums.aws.amazon.com/thread.jspa?messageID=879594

I have disabled a user in the cognito and the user is already in the app. Here it not shows any error for the user.

User can access the account after he is disabled.

So If I reload the app it shows the error that is not authenticated from Auth.currentAuthenticatedUser(). Also I can get the currentSession() of the disabled user.

How can I show the user is disabled message immediately the user is disabled from the cognito?

I am using aws-amplify-react-native package

What do you think about this workaround? - https://forums.aws.amazon.com/thread.jspa?messageID=879594

this process seems to work for me. I can confirm that:

1) Logging out using aws's hosted logout url https://XXXXXX.auth.us-east-1.amazoncognito.com/logout?client_id=xxxxxxabcxxxxxxc&logout_uri= ~revokes the access token (this does not revoke the refresh token)~ EDIT: Spoke to soon Token is still valid after going to the hosted logout page... may have been a fluke before.
2) To revoke the refresh token, the only option as of now is globalsignout (unfortunately, this revokes all refresh tokens for that user). NOTE: you can still call globalsignout after you revoke the access code in step 1

It’d be great if the Cognito SDK supported the strategy for mobile apps described in the top answer in this SO question: https://stackoverflow.com/questions/26739167/jwt-json-web-token-automatic-prolongation-of-expiration.

Basically have a way to invalidate a specific refresh token given the device ID where it was generated from. Looking at the current Cognito API it seems like it wouldn’t be that hard to support right? Given that globalSignOut already exists.

This is a long thread, so sorry if someone has already written about this.

What I wanted to share is the the opposite of this issue is also a problem: If a user is programatically added to a Cognito group, the permissions don't take effect until the user logs off/on.

In brief, if a graphQL type is setup with an @auth directive, like this (in schema.graphql):

type User
  @model
  @auth(
    rules: [
      { allow: owner }
      { allow: groups, groups: ["Managers"], operations: [read, update] }
    ]
  )
  @key(name: "byCompany", fields: ["companyId", "id"]) {
...

And then the user is added to the "Managers" group via a (node) lambda, like this:

const addToManagerGroup = (userName, userPoolId) => {
  return new Promise((resolve, reject) => {
    try {
      const params = {
        GroupName: "Managers",
        UserPoolId: userPoolId,
        Username: userName
      };
      const data = cognito.adminAddUserToGroup(params).promise();
      resolve(data);
    } catch (error) {
      reject(error);
    }
  });
};

If the user in the "Managers" group tries something like the following, without first logging off, after being added to the "Managers" group, the query is empty (unless they're the owner, which they won't be):

let { data } = await API.graphql(
      graphqlOperation(queries.listUsers, {
        filter: {
          companyId: { eq: companyId }
        },
        limit: 50
      })

After logging off/on, the the above query returns values as desired/expected.

If there is a way to allow this, without forcing a signOut, I'd love to learn what that is.

@kimfucious Have you tried using the InitiateAuth action with REFRESH_TOKEN auth to generate new Identity & Access Tokens? Groups & other claims should be on the Identity token, which can be refreshed on demand with this endpoint. You may want to open a separate issue if that does not work.

Thanks for this @ProdigySim

I've looked at that, and, frankly, I couldn't find any solid docs or examples that enabled me to learn exactly what I should do with InitateAuth().

At the risk of sounding overly whiney, I wish that Amplify would provide an auth method, like Auth.refreshTokens(), but I assume there are reasons why they haven't (yet).

Anyhow, while potentially off-topic to this thread, what I would up doing--and it appears to work thus far--is to call the following after any changes are made to a user in Cognito that would require the user to have updated permissions based on those changes:

const cognitoUser = await Auth.currentAuthenticatedUser();
const session = await Auth.currentSession();
const refreshToken = session.getRefreshToken();
cognitoUser.refreshSession(refreshToken, (error, session) => {
  if (error) {
    console.warn(error);
  } else {
    console.log("🙆 Tokens refreshed!", session);
  }
});

This prevents me from having to force a signOut.

We're at nearly 9 months since any update from AWS on this (@sammartinez on Jan 24). As others have stated, this is not something that can properly be fixed other than directly by the AWS team. ProdigySim hit the nail on the head further up the thread on this:

Developers using Cognito are forced to choose between good security and good user experience here.

We're a multi-platform app, and the inability to handle this token revocation on a case-by-case basis is extremely detrimental to our users' experience. Sadly, there are many things missing with Cognito that force us to either offer a poor UX, or compromise on security in someway; the other example we've run across is that there is no endpoint for re-sending a MFA code. Suggestion is simply 'hang on to the username and password and call login again', which just shouldn't be necessary.

Any chance of an update for this? I'm not sensing any commitment to actually fix this issue. This is a commercial product (admittedly with a rather generous free tier currently!), not an open source community library, so I would expect a little more interest from AWS on this... not least because Cognito is one of the 'gateway drugs' into the AWS ecosystem. If there's this little attention paid to basic functionality in Cognito, it worries me the amount of workarounds and step outs we're going to need for basic functionality in other parts of our AWS infrastructure moving forwards.

TLDR; grumble grumble. Any chance of an update? 😄

Thanks, @pinpointpanda! We're very committed to addressing the concerns on this thread. We're currently working behind the scenes on this. Sorry for saying stay tuned, but, please stay tuned! We will provide an update here as soon as we can.

Thanks for the update @jpignata - will keep my 👀 on the thread!

Just faced the same issue and was glad to see the last comment from @jpignata here was 19 days ago. Fingers crossed.

What happened to this issue? Has it been fixed @jpignata ?

Any updates?

Any updates?!

any good news about this?

Was this page helpful?
0 / 5 - 0 ratings

Related issues

callmekatootie picture callmekatootie  Â·  3Comments

lucasmike picture lucasmike  Â·  3Comments

benevolentprof picture benevolentprof  Â·  3Comments

shinnapatthesix picture shinnapatthesix  Â·  3Comments

rayhaanq picture rayhaanq  Â·  3Comments