最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - How to persist Cognito identity across pages in browser - Stack Overflow

programmeradmin5浏览0评论

I am authenticating through Cognito on client side browser using a developer authenticated identity. When my page loads (or is refreshed) I would like my application to remember the Identity for as long as the object is not expired (I think it lasts about an hour). However, I don't know how to retrieve the identity from Cognito without having to go through the developer authentication again.

Here is what the code does on page load:

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 the developer authentication:

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

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

However, I don't know how to access it. How do I retrieve the credentials so that when the page is refreshed, I can detect the previous identity given by Cognito?

I am authenticating through Cognito on client side browser using a developer authenticated identity. When my page loads (or is refreshed) I would like my application to remember the Identity for as long as the object is not expired (I think it lasts about an hour). However, I don't know how to retrieve the identity from Cognito without having to go through the developer authentication again.

Here is what the code does on page load:

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 the 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 refresh the page, and try to log in again I get an error that I am trying to get an identity when I already have one Error: Missing credentials in config(…) NotAuthorizedException: Missing credentials in config "Access to Identity 'us-east-1:xxxxxxx' is forbidden."

However, I don't know how to access it. How do I retrieve the credentials so that when the page is refreshed, I can detect the previous identity given by Cognito?

Share Improve this question edited Aug 15, 2019 at 12:08 JBaczuk asked Sep 16, 2015 at 15:12 JBaczukJBaczuk 14.6k10 gold badges65 silver badges90 bronze badges
Add a comment  | 

3 Answers 3

Reset to default 13

Save at least accessKeyId, secretAccessKey, sessionToken in sessionStorage between pages. You can load these into AWS.config.credentials (after the AWS SDK has been loaded of course). It is much faster than waiting for Cognito to respond. Keep in mind, you'll have to manually refresh them with a token from one of the providers 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

The only way to get back to the same identity on page refresh would be to use the same token used to initialize that identity. You may want to refer to this question as the problems are similar (replacing the Facebook token with the OpenId Connect token from the developer authenticated identities flow).

To reiterate what that question says: the credentials in the SDK will not be persisted across pages, so you should cache the token to be reused.

I take a slightly different approach, that allows the SDK to refresh the credentials.

In short, I serialize the AssumeRoleWithWebIdentityRequest JSON object to session storage.

Here is an example using Angular, but concept applies in any JS app:

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);
  }

...

Few things to note:

  • Upon login, I store the WebIdentityCredentials parameters as a JSON string in session cache.
  • You'll notice I check the browser session cache in global scope, to handle page refreshes (sets creds before they can be used).

A tutorial with complete example can be found on my blog

发布评论

评论列表(0)

  1. 暂无评论