【问题标题】:How to persist Cognito identity across pages in browser如何在浏览器中跨页面保留 Cognito 身份
【发布时间】:2015-12-13 06:31:51
【问题描述】:

我正在使用开发人员身份验证的身份通过客户端浏览器上的 Cognito 进行身份验证。当我的页面加载(或刷新)时,我希望我的应用程序记住身份,只要对象没有过期(我认为它会持续大约一个小时)。但是,我不知道如何从 Cognito 中检索身份,而无需再次通过开发者身份验证。

这是代码在页面加载时的作用:

var cognitoCredentials

$(document).ready(function() { 
    "use strict";

    cognitoParams = {
      IdentityPoolId: 'us-east-1:xxxxxxx'
    };

    cognitoCredentials = new AWS.CognitoIdentityCredentials(cognitoParams);
    AWS.config.credentials = cognitoCredentials;

});

并且通过开发者认证登录后:

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

如果我已经登录,然后刷新页面,然后再次尝试登录,我会收到一个错误,当我已经拥有身份时,我正在尝试获取身份 Error: Missing credentials in config(…) NotAuthorizedException: Missing credentials in config "Access to Identity 'us-east-1:xxxxxxx' is forbidden."

但是,我不知道如何访问它。如何检索凭据,以便在刷新页面时能够检测到 Cognito 之前提供的身份?

【问题讨论】:

    标签: javascript amazon-web-services amazon-cognito


    【解决方案1】:

    在页面之间至少保存accessKeyId, secretAccessKey, sessionToken 中的sessionStorage。您可以将这些加载到 AWS.config.credentials 中(当然是在加载 AWS 开发工具包之后)。这比等待 Cognito 响应要快得多。请记住,您必须使用来自其中一个提供商的令牌手动刷新它们,并且这仅在临时令牌过期(约 1 小时)之前有效。

    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

    【讨论】:

    • 我们有缓存,然后将其删除,现在我可能会将其添加回来。 cognito 从提供者令牌到 sts 大约需要 2 秒(平均),这在任何多页场景中都不可用。我希望这只是由 sdk 支持。
    【解决方案2】:

    在页面刷新时恢复相同身份的唯一方法是使用用于初始化该身份的相同令牌。您可能需要参考this question,因为问题相似(将 Facebook 令牌替换为开发人员身份验证流程中的 OpenId Connect 令牌)。

    重申这个问题的含义:SDK 中的凭据不会跨页面保留,因此您应该缓存令牌以供重复使用。

    【讨论】:

    • 是否有缓存令牌以使其自动过期的最佳做法?例如,我应该使用 sessionStorage 而不是 localStorage?
    • 在阅读中看起来浏览器存储或 cookie 是选项,它们各有利弊:stormpath.com/blog/…
    【解决方案3】:

    我采用稍微不同的方法,允许 SDK 刷新凭据。

    简而言之,我将AssumeRoleWithWebIdentityRequest JSON 对象序列化为会话存储。

    这是一个使用 Angular 的示例,但概念适用于任何 JS 应用程序:

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

    注意事项:

    • 登录后,我将 WebIdentityCredentials 参数作为 JSON 字符串存储在会话缓存中。
    • 您会注意到我在全局范围内检查浏览器会话缓存,以 处理页面刷新(在可以使用之前设置凭据)。

    可以在my blog上找到带有完整示例的教程

    【讨论】:

      猜你喜欢
      • 2013-05-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-22
      • 2018-11-05
      • 1970-01-01
      • 2015-11-05
      相关资源
      最近更新 更多