如何在浏览器

时间:2015-09-16 15:12:40

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

我使用开发人员身份验证身份在客户端浏览器上通过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:91fa684a-3d30-4b38-8705-450f10f086af' is forbidden."

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

3 个答案:

答案 0 :(得分:10)

在页面之间accessKeyId, secretAccessKey, sessionToken至少保存sessionStorage。您可以将这些加载到AWS.config.credentials中(当然,在加载AWS SDK之后)。它比等待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

答案 1 :(得分:2)

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

重申问题所说的内容:SDK中的凭据不会跨页面保留,因此您应该缓存令牌以便重复使用。

答案 2 :(得分:0)

我采用的方法稍有不同,该方法允许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上找到带有完整示例的教程