AWS Cognito - JavaScript(浏览器)中的开发人员身份验证
AWS Cognito - Developer Authenticated Identities in JavaScript(Browser)
我在浏览器脚本中获取凭据时遇到问题。
认证服务器returnscognito_identityId和cognito_token.
然后我设置一个Cookie:
- $.cookie('cognito_identityId')
- $.cookie('cognito_token')
我尝试在浏览器上通过 4 种方式获取凭据,但均失败:
CognitoIdentityCredentials
AWS.config.credentials = new AWS.CognitoIdentityCredentials({
IdentityPoolId: 'us-east-1:xxxxxxxxxxxx'
IdentityId: $.cookie('cognito_identityId'),
Logins: {
'myauth': $.cookie('cognito_token')
}
});
// => 错误:params
中缺少必需的键 'IdentityId'
assumeRoleWithWebIdentity
var params = {
RoleArn: 'arn:aws:iam::xxxxxxxxxxxx:role/Cognito_xxxxxxxAuth_Role',
RoleSessionName: 'xxxxxxxxxxx',
WebIdentityToken: $.cookie('cognito_token'),
DurationSeconds: 900,
ProviderId: 'myauth'
};
var sts = new AWS.STS({apiVersion: '2011-06-15'});
sts.assumeRoleWithWebIdentity(params, function(err, data) {
if (err) console.log(err, err.stack); // an error occurred
else console.log(data); // successful response
});
// => AccessDenied: 未授权执行 sts:AssumeRoleWithWebIdentity
政策文件
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "us-east-1:xxxxxxxxxxxxx"
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "authenticated"
}
}
}
]
}
GetCredentialsForIdentity
var params = {
IdentityId: $.cookie('cognito_identityId'),
Logins: {
"myauth": $.cookie('oauth.io_token')
}
};
var cognitoidentity = new AWS.CognitoIdentity({apiVersion: '2014-06-30'});
cognitoidentity.getCredentialsForIdentity(params, function(err, data) {
if (err) {
console.log(err, err.stack); // an error occurred
}
else {
console.log(data); // successful response
}
});
// => InvalidParameterException: 请提供有效的 public 提供商
WebIdentityCredentials
AWS.config.credentials = new AWS.WebIdentityCredentials({
RoleArn: 'arn:aws:iam::xxxxxxxx:role/Cognito_xxxxxxxxxxAuth_Role',
WebIdentityToken: $.cookie('cognito_token')
});
// => 错误:有 2 个验证错误:
// * MissingRequiredParameter:参数中缺少必需的键 'IdentityPoolId'
// * MissingRequiredParameter:缺少必需的键 'IdentityId' in params
问题:
我做错了什么?
正确的使用方法是什么?
谢谢。
谢谢你的好意。
我采纳了你的建议,但没有改变。
错误信息。
POST https://cognito-identity.us-east-1.amazonaws.com/ 400 (Bad Request)
POST https://cognito-identity.us-east-1.amazonaws.com/ 400 (Bad Request)
Error: Missing required key 'IdentityId' in params
at fail (chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:2163:37)
at validateStructure (chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:2084:14)
at validateMember (chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:2110:21)
at validate (chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:2059:10)
at Request.VALIDATE_PARAMETERS (chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:800:32)
at Request.callListeners (chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:3913:20)
at callNextListener (chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:3903:12)
at chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:787:9
at finish (chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:126:7)
at chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:142:9
下面有源码link.
https://github.com/bisque33/my-custom-dictionary
服务器端是 AWS Lambda 函数。
var aws = require('aws-sdk');
aws.config.region = 'us-east-1';
var cognitoidentity = new aws.CognitoIdentity();
var identityPoolId = 'us-east-1:0dccff0d-5fd7-4d14-b38f-d27204feaecc';
console.log('Loading function');
exports.handler = function(event, context) {
console.log('token: %s', event.token);
var params = {
IdentityPoolId: identityPoolId,
Logins: {
'oauth.io': event.token
}
};
cognitoidentity.getOpenIdTokenForDeveloperIdentity(params,function(err,data){
if(err){
console.log(err);
context.fail('Something went wrong');
}else{
context.succeed(data);
}
});
};
这个程序是Google-Chrome-扩展。
- AWS Lambda 函数 returns getOpenIdTokenForDeveloperIdentity 令牌。
- app/scripts/popup.js 调用 Lambda 函数并设置 cookie。
- app/scripts/background.js调用AWS.config.credentials.get,returns错误。
我是不是用错了?
附加信息更新
感谢您提供更多信息。
background.js
的 104 行出现错误
AWS.config.credentials.get(function(){
和 background.js
上的 115 行
dataset.synchronize(
而且,我的解释还不够。 Facebook 身份验证需要域(例如 http://example.com)。但是,Google-Chrome-Ext 没有域。它有一个域 'chrome-extension://xxxxxxxxxxxxxxxxxxxx'。然后,我使用 https://oauth.io。它代理任何身份验证并接受 chrome-扩展域。
Popup.js 通过oauth.io sdk 进行Facebook 身份验证。它获取一个 facebook 令牌,并提供给 getOpenIdTokenForDeveloperIdentity。我认为 facebook token.substr(0,14) 是独一无二的。但是,如果错了,我会使用另一个唯一标识符(例如电子邮件地址。)
对不起,我错了。 AWS.config.credentials.get 给出错误:
Error: Invalid login token.
并且,dataset.synchronize 显示此错误:
Error: Missing required key 'IdentityId' in params
您使用的第一种方法 CognitoIdentityCredentials 很可能是您可以采用的最佳方法。我无法准确找出导致错误的原因,但让我们尝试一些操作:
- 使用Developer Authenticated Identities时,需要在初始化CognitoIdentityCredentials时指定IdentityId。您需要从对 GetOpenIdTokenForDeveloperIdentity 的调用中获取 IdentityId 值。但是,您不需要在 cookie 中保留 IdentityId 值,因为 CognitoIdentityCredentials 默认情况下会将 id 缓存在浏览器的本地存储中。
- 至于您的登录地图:看起来您正在尝试使用 Developer Authenticated Identities。使用 JavaScript SDK,使用密钥
'cognito-identity.amazonaws.com'
并确保该值是从后端调用 getOpenIdTokenForDeveloperIdentity
. 返回的令牌
如果您在使用 CognitoIdentityCredentials 方法时仍然遇到问题,请在此处回复并提供更多信息,例如收到错误消息时您正在调用的确切 method/code 以及跟踪的输出(即使用console.log('%o',..)) 在您调用 CognitoIdentityCredentials 构造函数之前输入的参数。
根据提供的附加信息更新
我仍然需要确切地知道您在哪一行代码中收到错误,但根据提供的信息,我认为我仍然可以提供帮助...
根据我在 background.js 中看到的内容,您似乎正在尝试使用 Developer Authenticated Identities 提供商来初始化 CognitoIdentityCredentials。这是我猜你收到错误的地方。
然而,在Popup.js, it looks like you're trying to authenticate the user with Facebook. If you're authenticating your users with Facebook, you should just pass the facebook access token into your Logins map when using Cognito. Just use graph.facebook.com
as the key in the Logins map and the access token from Facebook. More detail on how to do this is in the Facebook Integration topic of the Amazon Cognito developer guide.
Facebook 与开发人员身份验证
我们可以让 Developer Authenticated Identities 为您工作,但在这种情况下,它看起来不是适合您的解决方案,因为您实际上并没有对 Lambda 函数中的身份进行任何额外的身份验证,并且您传递给 getOpenIdTokenForDeveloperIdentity
操作的唯一用户标识符似乎是 facebook 令牌,顺便说一下,这并不好,因为即使对于同一用户,令牌本身也会在用户会话之间发生变化。通常一个好的唯一标识符是内部系统使用的电子邮件地址或用户 ID。
Facebook 登录和重定向
由于您最终尝试使用 Facebook 进行登录,而 Amazon Cognito 具有 built-in integration for Facebook, the best thing for you to do is get an access token from Facebook and pass in the Facebook token to Cognito's login map directly. I'm not sure if this will work with Auth.io or not (I'm just not familiar with it), but as long as Auth.io gives your JavaScript code a bonefide facebook token and you add the same Facebook App ID to both Auth.io and Amazon Cognito's Console, it should work. However, you mentioned you want to use Auth.io to avoid Facebook doing a redirect to a landing page. I could be mistaken, but I'm pretty sure if you're using Facebook's JavaScript SDK you won't need a redirect page. You should only need the redirect page if you're doing Facebook's Manually Build a Login Flow。
我在浏览器脚本中获取凭据时遇到问题。
认证服务器returnscognito_identityId和cognito_token.
然后我设置一个Cookie:
- $.cookie('cognito_identityId')
- $.cookie('cognito_token')
我尝试在浏览器上通过 4 种方式获取凭据,但均失败:
CognitoIdentityCredentials
AWS.config.credentials = new AWS.CognitoIdentityCredentials({ IdentityPoolId: 'us-east-1:xxxxxxxxxxxx' IdentityId: $.cookie('cognito_identityId'), Logins: { 'myauth': $.cookie('cognito_token') } });
// => 错误:params
中缺少必需的键 'IdentityId'
assumeRoleWithWebIdentity
var params = { RoleArn: 'arn:aws:iam::xxxxxxxxxxxx:role/Cognito_xxxxxxxAuth_Role', RoleSessionName: 'xxxxxxxxxxx', WebIdentityToken: $.cookie('cognito_token'), DurationSeconds: 900, ProviderId: 'myauth' }; var sts = new AWS.STS({apiVersion: '2011-06-15'}); sts.assumeRoleWithWebIdentity(params, function(err, data) { if (err) console.log(err, err.stack); // an error occurred else console.log(data); // successful response });
// => AccessDenied: 未授权执行 sts:AssumeRoleWithWebIdentity
政策文件
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "",
"Effect": "Allow",
"Principal": {
"Federated": "cognito-identity.amazonaws.com"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"cognito-identity.amazonaws.com:aud": "us-east-1:xxxxxxxxxxxxx"
},
"ForAnyValue:StringLike": {
"cognito-identity.amazonaws.com:amr": "authenticated"
}
}
}
]
}
GetCredentialsForIdentity
var params = { IdentityId: $.cookie('cognito_identityId'), Logins: { "myauth": $.cookie('oauth.io_token') } }; var cognitoidentity = new AWS.CognitoIdentity({apiVersion: '2014-06-30'}); cognitoidentity.getCredentialsForIdentity(params, function(err, data) { if (err) { console.log(err, err.stack); // an error occurred } else { console.log(data); // successful response } });
// => InvalidParameterException: 请提供有效的 public 提供商
WebIdentityCredentials
AWS.config.credentials = new AWS.WebIdentityCredentials({ RoleArn: 'arn:aws:iam::xxxxxxxx:role/Cognito_xxxxxxxxxxAuth_Role', WebIdentityToken: $.cookie('cognito_token') });
// => 错误:有 2 个验证错误: // * MissingRequiredParameter:参数中缺少必需的键 'IdentityPoolId' // * MissingRequiredParameter:缺少必需的键 'IdentityId' in params
问题:
我做错了什么?
正确的使用方法是什么?
谢谢。
谢谢你的好意。
我采纳了你的建议,但没有改变。
错误信息。
POST https://cognito-identity.us-east-1.amazonaws.com/ 400 (Bad Request)
POST https://cognito-identity.us-east-1.amazonaws.com/ 400 (Bad Request)
Error: Missing required key 'IdentityId' in params
at fail (chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:2163:37)
at validateStructure (chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:2084:14)
at validateMember (chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:2110:21)
at validate (chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:2059:10)
at Request.VALIDATE_PARAMETERS (chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:800:32)
at Request.callListeners (chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:3913:20)
at callNextListener (chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:3903:12)
at chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:787:9
at finish (chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:126:7)
at chrome-extension://hmjdjbikinkmjbilihjibcihbkbjdgjf/bower_components/aws-sdk-js/dist/aws-sdk.js:142:9
下面有源码link.
https://github.com/bisque33/my-custom-dictionary
服务器端是 AWS Lambda 函数。
var aws = require('aws-sdk');
aws.config.region = 'us-east-1';
var cognitoidentity = new aws.CognitoIdentity();
var identityPoolId = 'us-east-1:0dccff0d-5fd7-4d14-b38f-d27204feaecc';
console.log('Loading function');
exports.handler = function(event, context) {
console.log('token: %s', event.token);
var params = {
IdentityPoolId: identityPoolId,
Logins: {
'oauth.io': event.token
}
};
cognitoidentity.getOpenIdTokenForDeveloperIdentity(params,function(err,data){
if(err){
console.log(err);
context.fail('Something went wrong');
}else{
context.succeed(data);
}
});
};
这个程序是Google-Chrome-扩展。
- AWS Lambda 函数 returns getOpenIdTokenForDeveloperIdentity 令牌。
- app/scripts/popup.js 调用 Lambda 函数并设置 cookie。
- app/scripts/background.js调用AWS.config.credentials.get,returns错误。
我是不是用错了?
附加信息更新
感谢您提供更多信息。
background.js
的 104 行出现错误AWS.config.credentials.get(function(){
和 background.js
上的 115 行 dataset.synchronize(
而且,我的解释还不够。 Facebook 身份验证需要域(例如 http://example.com)。但是,Google-Chrome-Ext 没有域。它有一个域 'chrome-extension://xxxxxxxxxxxxxxxxxxxx'。然后,我使用 https://oauth.io。它代理任何身份验证并接受 chrome-扩展域。
Popup.js 通过oauth.io sdk 进行Facebook 身份验证。它获取一个 facebook 令牌,并提供给 getOpenIdTokenForDeveloperIdentity。我认为 facebook token.substr(0,14) 是独一无二的。但是,如果错了,我会使用另一个唯一标识符(例如电子邮件地址。)
对不起,我错了。 AWS.config.credentials.get 给出错误:
Error: Invalid login token.
并且,dataset.synchronize 显示此错误:
Error: Missing required key 'IdentityId' in params
您使用的第一种方法 CognitoIdentityCredentials 很可能是您可以采用的最佳方法。我无法准确找出导致错误的原因,但让我们尝试一些操作:
- 使用Developer Authenticated Identities时,需要在初始化CognitoIdentityCredentials时指定IdentityId。您需要从对 GetOpenIdTokenForDeveloperIdentity 的调用中获取 IdentityId 值。但是,您不需要在 cookie 中保留 IdentityId 值,因为 CognitoIdentityCredentials 默认情况下会将 id 缓存在浏览器的本地存储中。
- 至于您的登录地图:看起来您正在尝试使用 Developer Authenticated Identities。使用 JavaScript SDK,使用密钥
'cognito-identity.amazonaws.com'
并确保该值是从后端调用getOpenIdTokenForDeveloperIdentity
. 返回的令牌
如果您在使用 CognitoIdentityCredentials 方法时仍然遇到问题,请在此处回复并提供更多信息,例如收到错误消息时您正在调用的确切 method/code 以及跟踪的输出(即使用console.log('%o',..)) 在您调用 CognitoIdentityCredentials 构造函数之前输入的参数。
根据提供的附加信息更新
我仍然需要确切地知道您在哪一行代码中收到错误,但根据提供的信息,我认为我仍然可以提供帮助...
根据我在 background.js 中看到的内容,您似乎正在尝试使用 Developer Authenticated Identities 提供商来初始化 CognitoIdentityCredentials。这是我猜你收到错误的地方。
然而,在Popup.js, it looks like you're trying to authenticate the user with Facebook. If you're authenticating your users with Facebook, you should just pass the facebook access token into your Logins map when using Cognito. Just use graph.facebook.com
as the key in the Logins map and the access token from Facebook. More detail on how to do this is in the Facebook Integration topic of the Amazon Cognito developer guide.
Facebook 与开发人员身份验证
我们可以让 Developer Authenticated Identities 为您工作,但在这种情况下,它看起来不是适合您的解决方案,因为您实际上并没有对 Lambda 函数中的身份进行任何额外的身份验证,并且您传递给 getOpenIdTokenForDeveloperIdentity
操作的唯一用户标识符似乎是 facebook 令牌,顺便说一下,这并不好,因为即使对于同一用户,令牌本身也会在用户会话之间发生变化。通常一个好的唯一标识符是内部系统使用的电子邮件地址或用户 ID。
Facebook 登录和重定向
由于您最终尝试使用 Facebook 进行登录,而 Amazon Cognito 具有 built-in integration for Facebook, the best thing for you to do is get an access token from Facebook and pass in the Facebook token to Cognito's login map directly. I'm not sure if this will work with Auth.io or not (I'm just not familiar with it), but as long as Auth.io gives your JavaScript code a bonefide facebook token and you add the same Facebook App ID to both Auth.io and Amazon Cognito's Console, it should work. However, you mentioned you want to use Auth.io to avoid Facebook doing a redirect to a landing page. I could be mistaken, but I'm pretty sure if you're using Facebook's JavaScript SDK you won't need a redirect page. You should only need the redirect page if you're doing Facebook's Manually Build a Login Flow。