如何在使用AWS Amplify进行注册时将用户放入特定的身份验证池中?

huangapple go评论76阅读模式
英文:

How to place users into specific authentication pools on sign up with AWS Amplify?

问题

这似乎应该是大多数网站的常见功能,但我没有看到任何相关文档。我的网站有三个使用者群体:

  1. 客户
  2. 教师
  3. 管理员

当客户使用 Authenticator 组件注册时,它目前会将用户添加到 Cognito 用户池,但不会添加到任何特定的群组。我想捕获这个注册请求,然后在“客户”池中创建一个新的 Cognito 用户。

我有一个 GraphQL 模式,允许根据 Cognito 群组访问数据:

type ClassGroup @model @auth(rules: [{allow: public, operations: [read]}, {allow: groups, groups: ["admins"], operations: [read, create, update, delete]}]) {
  id: ID!
  className: String
  semesterPrice: Float
}

为了进行该群组更改,我必须在 Amplify 控制台内手动执行:
如何在使用AWS Amplify进行注册时将用户放入特定的身份验证池中?
如何在使用AWS Amplify进行注册时将用户放入特定的身份验证池中?

我如何实现用户和数据可访问性的这种分离?如何允许一组用户访问某些数据,而其他用户访问其他数据?

英文:

I assume this is should be a common feature of most websites, but I have seen no documentation for it. I have a website that has three groups of people that use it:

  1. Clients
  2. Teachers
  3. Admins

When a client signs up with the Authenticator Component, it currently adds the user to the Cognito pool, but not to any specific group. I would like to capture this sign-up request, then create a new cognito user inside the Client pool.

I have a graphql schema that allows access to data based on the cognito group:

type ClassGroup @model @auth(rules: [{allow: public, operations: [read]}, {allow: groups, groups: ["admins"], operations: [read, create, update, delete]}]) {
  id: ID!
  className: String
  semesterPrice: Float
}

To make that group change, I have to do it manually inside the Amplify Console:
如何在使用AWS Amplify进行注册时将用户放入特定的身份验证池中?
如何在使用AWS Amplify进行注册时将用户放入特定的身份验证池中?

I
How can I accomplish this separation of users and accessibility inside AWS? How can I allow one group of users to access certain data and other users to access other data?

答案1

得分: 1

你的GraphQL模式可以如下所示:

type EmployerAccount
  @model
  @auth(
    rules: [
      { allow: owner, operations: [create, update, delete, read] }
      { allow: private, operations: [read] }
      { allow: public, provider: iam, operations: [read] }
    ]
  ) {
...
}

你可以在Cognito池中添加一个custom:group属性,像这样:

await Auth.signUp({
  username: email,
  password,
  attributes: {
    "custom:group": "Employer"
  },
});

然后,你可以在Cognito池上使用Post Confirmation Lambda函数将用户发送到特定的表。

CLI:

运行 amplify update auth 并将这个函数添加为触发器。

Lambda函数

/**
 * @type {import('@types/aws-lambda').APIGatewayProxyHandler}
 */
var dynamodb = require("aws-sdk/clients/dynamodb");
var ddb = new dynamodb({ region: "eu-west-1" });

exports.handler = async (event, context) => {
  console.log("EVENT", event);
  console.log("CONTEXT", context);

  let date = new Date();

  // 由于这是一个PostConfirmation触发器,它可以被其他事件触发
  // 我们只想在triggerSource为PostConfirmation_ConfirmSignUp时运行以下代码
  // 另一个可能是"forgot_password"(我们不想运行此代码)

  const valueTrigger = event.triggerSource;
  const confirmSignUp = "PostConfirmation_ConfirmSignUp";

  // 如果triggerSource为PostConfirmation_ConfirmSignUp,那么我们知道用户刚刚注册
  if (valueTrigger === confirmSignUp) {
    // 只有当用户具有sub(唯一用户ID)时才运行下面的代码
    if (event.request.userAttributes.sub) {

      // 我们将使用他们的自定义组来确定需要传递给DynamoDB调用的参数
      const paramsToUse = event.request.userAttributes["custom:group"] === "Employer" ? candidateParams : employerParams;

      // 这些是我们需要传递给DynamoDB的初始用户创建的参数
      let params = {
        Item: {...},
        TableName:
          event.request.userAttributes["custom:group"] === "Candidates"
            ? process.env[TABLE_NAME]
            : process.env[TABLE_NAME],
      };

      try {
        await ddb.putItem(params).promise();
      } catch (err) {
        console.error("ERROR", err);
      }
      console.log("Success: Everything executed correctly");
      context.done(null, event);
    } else {
      console.error("ERROR: Nothing was written to DynamoDB");
      context.done(null, event);
    }
  } else {
    console.log("Not Confirm Signup, thus not running the code");
    context.done(null, event);
  }
};

希望这些信息对你有帮助。

英文:

Your graphql Schema can look like this:

type EmployerAccount
@model
@auth(
rules: [
{ allow: owner, operations: [create, update, delete, read] }
{ allow: private, operations: [read] }
{ allow: public, provider: iam, operations: [read] }
]
) {
...
}

You can add a custom:group attribute in your cognito pool like this:

  await Auth.signUp({
username: email,
password,
attributes: {
"custom:group": "Employer"
},
});

You can then use a Post Confirmation Lambda Function on your Cognito pool to send them to specific tables.

CLI:

Run amplify update auth and add this as a trigger.

Lambda Function

/**
* @type {import('@types/aws-lambda').APIGatewayProxyHandler}
*/
var dynamodb = require("aws-sdk/clients/dynamodb");
var ddb = new dynamodb({ region: "eu-west-1" });
exports.handler = async (event, context) => {
console.log("EVENT", event);
console.log("CONTEXT", context);
let date = new Date();
// As this is a PostConfirmation trigger, it can be triggered by other events
// We only want to run the code below if the triggerSource is PostConfirmation_ConfirmSignUp
// The other one is possibly "forgot_password" (which we don't want to run this code for)
const valueTrigger = event.triggerSource;
const confirmSignUp = "PostConfirmation_ConfirmSignUp";
// If the triggerSource is PostConfirmation_ConfirmSignUp, then we know that the user has just signed up
if (valueTrigger === confirmSignUp) {
// We only want to run the code below if the user has a sub (unique user ID)
if (event.request.userAttributes.sub) {
// I will use their custom group to determine which parameters need to be passed into the DynamoDB call
const paramsToUse = event.request.userAttributes["custom:group"] === "eMPLOYER" ? candidateParams : employerParams;
// These are the parameters we need to pass to DynamoDB for the initial user creation
let params = {
Item: {...},
TableName:
event.request.userAttributes["custom:group"] === "Candidates"
? process.env[TABLE_NAME]
: process.env.[TABLE_NAME],
};
try {
await ddb.putItem(params).promise();
} catch (err) {
console.error("ERROR", err);
}
console.log("Success: Everything executed correctly");
context.done(null, event);
} else {
console.error("ERROR: Nothing was written to DynamoDB");
context.done(null, event);
}
} else {
console.log("Not Confirm Signup, thus not running the code");
context.done(null, event);
}
};

huangapple
  • 本文由 发表于 2023年2月24日 07:00:48
  • 转载请务必保留本文链接:https://go.coder-hub.com/75551183.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定