Can I easily pass identity information to multiple subdomain with AWS Cognito? If I have three applications (app1.example.com, app2.example.com, app3.example.com), how can I sign into app1, then pass the identity information to app2 and app3? I've read docs and seen methods such as getIdToken().getJwtToken
, but I havn't seen how to pass such data to so I can use the identity.
//Login.ts
let cognitoUser = new CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, function(){
onSuccess: function(result){
let jwt = result.getIdToken().getJwtToken();
//Is it possible to pass this jwt token (or something else)
//to app2 and app3 so I can later fetch the user from the identity pool from those apps?
}
});
You can achieve SSO across all your subdomains by using the CookieStorage class from the JS SDK while creating the CognitoUserPool objects. When the authentication tokens received from Cognito are stored in cookies (instead of LocalStorage), they are available on all the sub-domains also. So calls to CognitoUserPool.getCurrentUser() and CognitoUserPool.getSession() will return the tokens from all sub-domains.
TypeScript Code snippets below
Full implementation can be found here. A running application can be viewed here.
To authenticate the User (on the main domain, say, example.com) -
signIn(email: string, password: string): Observable<any> {
let userPool = new CognitoUserPool({
UserPoolId: environment._USER_POOL_ID,
ClientId: environment._CLIENT_ID,
Storage: new CookieStorage({secure: false, domain: "example.com"}),
});
let authenticationDetails = new AuthenticationDetails({
Username: email,
Password: password,
});
let userData = {
Username: email,
Pool: userPool,
Storage: new CookieStorage({secure: false, domain: "example.com"}),
};
let cognitoUser = new CognitoUser(userData);
return Observable.create((observer: Observer<any>) => {
cognitoUser.authenticateUser(authenticationDetails, {
onSuccess: result => {
observer.next(result);
observer.complete();
},
onFailure: error => observer.error(error),
});
});
}
To check if user is authenticated (on a subdomain, say, sub.example.com)
isAuthenticated(): Observable<boolean> {
let userPool = new CognitoUserPool({
UserPoolId: environment._USER_POOL_ID,
ClientId: environment._CLIENT_ID,
Storage: new CookieStorage({secure: false, domain: "example.com"}),
});
let cognitoUser = userPool.getCurrentUser();
if (cognitoUser != null) {
return Observable.create((observer: Observer<boolean>) => {
cognitoUser.getSession((error, session) => {
if (error) {
console.error(error);
observer.next(false);
observer.complete();
}
console.log(session, session.isValid(), session.isAuthenticated);
observer.next(session.isValid());
observer.complete();
});
})
}
First of all, application subdomain, doesn't have a direct connection with AWS Cognito.
If you have subdomains and need to authenticate users using a single Cognito Userpool while also checking the link of the identity with the subdomain (Assuming upon user registration, they get registered from a particular subdomain app), you need to either store that information in a custom attribute in Cognito User or in your storage backend linking with the Cognito ID and subdomain, and verify it in code while user authenticates.
//Login.ts
let cognitoUser = new CognitoUser(userData);
cognitoUser.authenticateUser(authenticationDetails, function(){
onSuccess: function(result){
// Also check the user custom attribute comparing with the request subdomain.
let jwt = result.getIdToken().getJwtToken();
//You can pass this jwt token back to the client
//Each app can later fetch user data from identity pool
}
});
Note: If you use Hosted UI for the Login, the flow might be slightly different, since you need to create three client apps with different callback urls for each subdomain.
I'm trying to develop a solutions similar to Google's auth process. You sign in once to accounts.google.com, then that session is used for mail.google.com, news.google.com, etc. You don't need to login into each application manually. Once I log into accounts.myapp.com, I need to pass the user's auth to mail.myapp.com and news.myapp.com. I don't see in the AWS docs how I can create an instance of the Cognito client (from mail.myapp.com, or news.myapp.com) from the identity created in accounts.myapp.com
This is achievable using Cognito UserPools.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With