我正在使用 AWS Amplify 库注册 AppSync 项目并执行身份验证。这使用了 Cognito。但是,当新用户通过 Amplify/Cognito 注册时,新用户不会分配到 cognito 池中的任何特定组。我正在使用 Amplify 高阶组件进行登录/注册。
import { withAuthenticator } from 'aws-amplify-react';
我包裹在一个组件上
class Authenticator extends React.Component {
//... basically empty component, only exists so I can wrap it w/ the HOC
}
export default withAuthenticator(Authenticator)
Amplify是在index.js中设置的
import config from './aws-exports';
import Amplify from 'aws-amplify';
Amplify.configure(config);
aws-exports.js 由 AWS Mobile Hub CLI 自动生成。看起来像...
const awsmobile = {
'aws_app_analytics': 'enable',
'aws_cognito_identity_pool_id': 'us-west-2:XXX',
'aws_cognito_region': 'us-west-2',
'aws_content_delivery': 'enable',
'aws_content_delivery_bucket': 'flashcards-hosting-mobilehub-XXX',
'aws_content_delivery_bucket_region': 'us-west-2',
'aws_content_delivery_cloudfront': 'enable',
'aws_content_delivery_cloudfront_domain': 'XXX.cloudfront.net',
'aws_mandatory_sign_in': 'enable',
'aws_mobile_analytics_app_id': 'XXX',
'aws_mobile_analytics_app_region': 'us-east-1',
'aws_project_id': 'XXX',
'aws_project_name': 'flash-cards',
'aws_project_region': 'us-west-2',
'aws_resource_name_prefix': 'flashcards-mobilehub-XXX',
'aws_sign_in_enabled': 'enable',
'aws_user_pools': 'enable',
'aws_user_pools_id': 'us-west-2_XXX',
'aws_user_pools_mfa_type': 'OFF',
'aws_user_pools_web_client_id': 'XXX',
}
export default awsmobile;
我成功了。正如 Vladamir 在评论中提到的,这需要在服务器端、在确认后 lambda 触发器中完成。这是 lambda 函数。
'use strict';
var AWS = require('aws-sdk');
module.exports.addUserToGroup = (event, context, callback) => {
// console.log("howdy!",event);
var cognitoidentityserviceprovider = new AWS.CognitoIdentityServiceProvider();
var params = {
GroupName: 'users', //The name of the group in you cognito user pool that you want to add the user to
UserPoolId: event.userPoolId,
Username: event.userName
};
//some minimal checks to make sure the user was properly confirmed
if(! (event.request.userAttributes["cognito:user_status"]==="CONFIRMED" && event.request.userAttributes.email_verified==="true") )
callback("User was not properly confirmed and/or email not verified")
cognitoidentityserviceprovider.adminAddUserToGroup(params, function(err, data) {
if (err) {
callback(err) // an error occurred
}
callback(null, event); // successful response
});
};
您还必须为 lambda 函数角色设置策略。在 IAM 控制台中,找到此 lambda 的角色并添加此内联策略。这给了 lambda 一切认知的城堡钥匙,所以让你的更加严格。
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Action": [
"cognito-identity:*"
],
"Resource": "*"
},
{
"Effect": "Allow",
"Action": [
"cognito-sync:*"
],
"Resource": "*"
},
{ //this might be the only one you really need
"Effect": "Allow",
"Action": [
"cognito-idp:*"
],
"Resource": "*"
}
]
}
Cognito 不会知道新注册的用户需要加入哪个组。您必须以编程方式(或手动)将用户分配到特定组。一旦您的代码将用户放入特定组,JWT ID 令牌将包含该用户所属的所有相关组/IAM 角色的列表。
有关群组的更多信息此处。
AWS Amplify 添加了对使用 amplify cli 将用户添加到组的支持。详细信息请参见此处 https://aws.amazon.com/blogs/mobile/amplify-framework-adds-supports-for-aws-lambda-triggers-in-auth-and-storage-categories/
这篇文章还解释了更多细节 https://medium.com/@dantasfiles/multi-tenant-aws-amplify-method-2-cognito-groups-38b40ace2e9e
将组名称从客户端传递给您的 lamda 函数,您可以使用确认后 Lambda 触发器参数 clientMetadata 对象,如下所示。
await Auth.signUp({
username: this.email,
password: this.password,
attributes: {
given_name: this.firstname,
family_name: this.lastname
},
clientMetadata: {
key: value
}
})
如果您使用现成的 amplify auth UI,那么您需要自定义 withAuthenticator 组件并编写您自己的组件用于注册或首选ConfirmSignUp(请检查是否可以从那里传递 clientMetadata)
在 lamda 函数中,您可以像这样获取传递的组名称
event.request.clientMetadata.groupName
您必须首先使用 amplify cli 添加管理查询,运行
amplify update auth
,之后您必须仅阻止管理员用户的管理查询,您将在 amplify/backend/function/
中看到输出代码
推送更改后,您可以使用:
async function addToGroup() {
let apiName = 'AdminQueries';
let path = '/addUserToGroup';
let myInit = {
body: {
"username" : "username",
"groupname": "groupname"
},
headers: {
'Content-Type' : 'application/json',
Authorization: `${(await Auth.currentSession()).getAccessToken().getJwtToken()}`
}
}
return await API.post(apiName, path, myInit);
}
为了使用 amplify 将用户添加到角色,请检查用户 ID(如果仅使用电子邮件注册)。有关 amplify 中此更改的文档可在此处获取 https://aws.amazon.com/es/blogs/mobile/amplify-framework-adds-supports-for-aws-lambda-triggers-in-auth-and-storage-类别/
有人想知道如何在节点 18+ 中运行 @honkskillet 的代码,下面是我使用的代码。这当然是基于他的回答。他的回答中提到的所有权限配置仍然有效。 (https://stackoverflow.com/a/50003946/6686446)
const { CognitoIdentityProviderClient, AdminAddUserToGroupCommand } = require("@aws-sdk/client-cognito-identity-provider"); // CommonJS import
exports.handler = async (event, context, callback) => {
var client = new CognitoIdentityProviderClient();
var params = {
GroupName: 'clients', //The name of the group in you cognito user pool that you want to add the user to
UserPoolId: event.userPoolId,
Username: event.userName
};
//some minimal checks to make sure the user was properly confirmed
if(! (event.request.userAttributes["cognito:user_status"]==="CONFIRMED" && event.request.userAttributes.email_verified==="true") ){
callback("User was not properly confirmed and/or email not verified")
}
try {
const command = new AdminAddUserToGroupCommand(params);
const response = await client.send(command);
callback(null, event); // successful response
} catch (err) {
callback(err) // an error occurred
}
};
并安装
@aws-sdk/client-cognito-identity-provider": "^3.462.0