Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Preventing multiple simultaneous logins with Cognito

We have React Native app that uses Cognito for authentication. We would like to prevent the same user ID from logging in simultaneously from multiple devices.

We were hopefully that we could use a Cognito pre-authentication trigger for this. Unfortunately it seems that we can't just call globalSignOut for the user since that wouldn't invalidate tokens that have already been issued and are currently active (see https://github.com/amazon-archives/amazon-cognito-identity-js/issues/21#issuecomment-331472144).

The other idea was to reject the login if the user is logged in elsewhere. But we can't see a reliable way to tell whether the user is already logged in. We can see if there are valid tokens issued for that user but not if they are currently associated with an active session.

We also thought of maintaining our own DB of active sessions but there is no sign-out trigger so we wouldn't know when to remove a session from the DB.

like image 596
Matthew Gertner Avatar asked Mar 22 '19 15:03

Matthew Gertner


People also ask

Is Cognito Multi AZ?

In each Region, Amazon Cognito is distributed across multiple Availability Zones. These Availability Zones are physically isolated from each other, but are united by private, low-latency, high-throughput, and highly redundant network connections.

Does Cognito provide SSO?

Your user pool acts as a service provider (SP) on behalf of your application. Amazon Cognito supports SP-initiated single sign-on (SSO) as described in section 5.1.

What is user sub in Cognito?

The sub claim is a unique identifier (UUID) for the authenticated user. It is not the same as the user name, which might not be unique. Issuer ( iss ) The iss claim has the following format: https://cognito-idp.


2 Answers

You can use a token authentication system,

Issue a brand new token for each login, and check for available tokens.

if any token is available for the user that means He/She is logged in some other device, for this case you can prompt user that You are logged in other device.. are you sure you want to log out from that device ? and after clicking yes, you can clear all tokens for that user. And issue a brand new token.

AUTO LOGOUT : this token should be passed all over the back-end i.e. in headers of each and every API call token should be there... and should be checked before doing anything in back-end. if token is not available then throw 401. In your app if any API throws 401 then it means user is UNAUTHORIZED and should be logged out.

or

your app should be listening to one socket that responds to log out when it receives a message of same. so whenever your user logs in, a logout message will be passed across sockets and appropriate device with some token id or unique id will get that message and will log out a particular user from all other devices.

or

have a notification receiver which will be used to log out whenever necessary same as socket.

like image 151
Jaydeep Galani Avatar answered Sep 26 '22 05:09

Jaydeep Galani


Reading the link you provided the API token / session system seems being faulty by design since long time already.
So without an own token-system inside cognito you won't have reliable results probably, at least in the current state of the system (as the repository is archived it won't be developed further by the owner).

What I propose is an own field in the database-table for users where each login is honored with an own token. A second own field in the same table with a timestamp, where the last access is saved. If last access is older than a predefined time of 30, 60 or 120 minutes any user gets logged out. If the last access is younger than the time-limit then the login-mask has to provide a random access token which is compared with that in the database:
- if the access-token in the database is too old for an active session, or just no access-token is stored, then access can be granted which means login is successful.
- the comparison of the current time with the time-stamp saved in the database is for cases where users never have been logged out by purpose but just by being disconnected or passive. I think this case will happen regularly, so it's no exception.
- logging out by click on a button should destroy the access-token in the database, so that the user can immediately login from any device, even from another one then before.
- if there exists a valid access-token in the database then no new access will be granted and the user should get shown a message that he has to sign out first at another login.
- The access-token could be stored together with a third own field for the session-id to make it more reliable and safe. On logout that session-token-field can be cleared too. The session-token can be copied from the global session if required to be saved in the user-record.
- Any checks are only done on login, tokens never have to be included on every page.
- On active logout the token(s) have to be destroyed to allow a direct login again, else the users had to wait till the max. age of the time-limit is reached to login again - at least on another device then before.

As the login itself is currently done independent from the check that has to be implemented, it would be possible to leave the new access-token completely away but use only the session-id as that differs on any device and browser. But perhaps there exists a situation where one of session-id and access-token can change but the other one not - I don't think so but perhaps I missed something in my considerations.

If you provide the access-token on every page like proposed by @Jadeep Galani or in a cookie - beside the corresponding check - you also can offer a button to sign out from all devices. This would enable the users to change login any time even without logging out at the last used device. Without access-token on every page or in a cookie this general logout-function solution is not possible as else access is only checked on login but not on all pages.

A general question is if it's still worth it to rely on the buggy cognito for login or just replace it completely by an own solution. You even could implement the desired authentication in your site in form of a wrapper-class and the concrete login-system could be replaced without changing that implementation.

like image 42
David Avatar answered Sep 25 '22 05:09

David