How to maintain Cognito identity on pages in a browser

I authenticate through Cognito in the client-side browser using the authentication authenticated by the developer. When my page loads (or refreshes), I would like my application to remember Identity until the object has expired (I think it lasts about an hour). However, I do not know how to obtain an identity from Cognito without having to re-authenticate the developer.

Here is what the code does when the page loads:

var cognitoCredentials $(document).ready(function() { "use strict"; cognitoParams = { IdentityPoolId: 'us-east-1:xxxxxxx' }; cognitoCredentials = new AWS.CognitoIdentityCredentials(cognitoParams); AWS.config.credentials = cognitoCredentials; }); 

And after logging in through developer authentication:

 cognitoCredentials.params.IdentityId = output.identityId; cognitoCredentials.params.Logins = { 'cognito-identity.amazonaws.com': output.token }; cognitoCredentials.expired = true; 

If I have already logged in and then refreshed the page and tried to log in again, I get an error message that I am trying to get an ID when I already have Error: Missing credentials in config(…) NotAuthorizedException: Missing credentials in config "Access to Identity 'us-east-1:xxxxxxx' is forbidden."

However, I do not know how to access it. How do I get credentials so that when I refresh the page, I can find the previous credentials set by Cognito?

+11
source share
3 answers

The only way to return to the same identifier when updating the page is to use the same token that is used to initialize this identifier. You can address this issue , since the problems are similar (replacing the Facebook token with the OpenId Connect token from the stream of authenticated developer identifiers).

To repeat what this question says: credentials in the SDK will not be stored on different pages, so you have to cache the token that will be reused.

+2
source

Save at least accessKeyId, secretAccessKey, sessionToken in sessionStorage between pages. You can load them in AWS.config.credentials (after loading the AWS SDK, of course). This is much faster than waiting for Cognito to respond. Keep in mind, you will have to manually update them using a token from one of the suppliers, and this is only good until the temporary token expires (~ 1 hour).

 var credKeys = [ 'accessKeyId', 'secretAccessKey', 'sessionToken' ]; // After Cognito login credKeys.forEach(function(key) { sessionStorage.setItem(key, AWS.config.credentials[key]); }); // After AWS SDK load AWS.config.region = 'us-east-1'; // pick your region credKeys.forEach(function(key) { AWS.config.credentials[key] = sessionStorage.getItem(key); }); // Now make your AWS calls to S3, DynamoDB, etc 
+11
source

I use a slightly different approach that allows the SDK to update credentials.

In short, I am serializing the JSON AssumeRoleWithWebIdentityRequest object in the session store.

Here is an example of using Angular, but the concept is applicable in any JS application:

 const AWS = require('aws-sdk/global'); import { STS } from 'aws-sdk'; import { environment } from '../../environments/environment'; const WEB_IDENT_CREDS_SS_KEY = 'ic.tmpAwsCreds'; // Handle tmp aws creds across page refreshes const tmpCreds = sessionStorage.getItem(WEB_IDENT_CREDS_SS_KEY); if (!!tmpCreds) { AWS.config.credentials = new AWS.WebIdentityCredentials(JSON.parse(tmpCreds)); } @Injectable({ providedIn: 'root' }) export class AuthService { ... async assumeAwsRoleFromWebIdent(fbUser: firebase.User) { const token = await fbUser.getIdToken(false); let p: STS.Types.AssumeRoleWithWebIdentityRequest = { ...environment.stsAssumeWebIdentConfig, //environment.stsAssumeWebIdentConfig contains: //DurationSeconds: 3600, //RoleArn: 'arn:aws:iam::xxx:role/investmentclub-fbase-trust', RoleSessionName: fbUser.uid + '@' + (+new Date()), WebIdentityToken: token }; // Store creds across page refresh, duno WTF 'new AWS.WebIdentityCredentials(p)' don't have an option for this AWS.config.credentials = new AWS.WebIdentityCredentials(p); sessionStorage.setItem(WEB_IDENT_CREDS_SS_KEY, JSON.stringify(p)); } removeAwsTempCreds() { AWS.config.credentials = {}; sessionStorage.removeItem(WEB_IDENT_CREDS_SS_KEY); } ... 

A few notes:

  • After logging in, I save the WebIdentityCredentials parameters as a JSON string in the session cache.
  • You will notice that I check the browser session cache in the global scope to handle page updates (installs credits before they can be used).

A tutorial with a complete example can be found on my blog.

0
source

All Articles