created: 2019-03-23T02:54:52.000Z

cognitoで特定ドメインのGoogleアカウントだけsignUpさせる

lambda trigger を設定できるのでこの関数の中で可否を判定する

やり方

serverless framework を使うとこんな設定ができる trigger: PreSignUp の設定で、ユーザの新規登録前にチェックができる

  SignUpValidation:
    handler: handler.signUpValidation
    memorySize: 128
    events:
      - cognitoUserPool:
          pool: MyPoolId
          trigger: PreSignUp

設定できるトリガーは他にも色々ある

注意

  • serverless frameworkでは既存のUserPoolをpoolとして設定できない (新規作成のみ)
  • すでにPoolを作ってしまっている場合は関数だけ作ってUIから手動で紐付けとなる

新規作成する場合も最低限の設定で作られてしまうので適宜上書きする必要がありそう

lambda上での処理の書き方

たとえばemailで特定のドメインのみ許可したいという場合は以下のようになる

import { CognitoUserPoolTriggerEvent, Context } from 'aws-lambda';

export default (event: CognitoUserPoolTriggerEvent, context: Context) => {
  const { email } = event.request.userAttributes;
  if (email) {
    const domain = email.split('@')[1];
    // 認証しない場合は空のオブジェクトを返してinvalid-lambda-responseとする
    context.done(undefined, domain === 'mydomain.jp' ? event : null);
  }
};

cognito側に認証可否を伝達するために context.done(undefined, event) を呼ぶ必要がある

eventオブジェクト

lambda関数に渡される [event, context] はこんな感じ

[
  {
    "version": "1",
    "region": "ap-northeast-1",
    "userPoolId": "ap-northeast-1_asdfjhf9m",
    "userName": "Google_103571795941234567890",
    "callerContext": {
      "awsSdkVersion": "aws-sdk-unknown-unknown",
      "clientId": "123456789i9mrulbr36pasdfa5"
    },
    "triggerSource": "PreSignUp_ExternalProvider",
    "request": {
      "userAttributes": {
        "cognito:email_alias": "",
        "cognito:phone_number_alias": "",
        "email": "forspammymail@gmail.com"
      },
      "validationData": {}
    },
    "response": {
      "autoConfirmUser": false,
      "autoVerifyEmail": false,
      "autoVerifyPhone": false
    }
  },
  {
    "callbackWaitsForEmptyEventLoop": true,
    "logGroupName": "/aws/lambda/SignUpValidation",
    "logStreamName": "2019/03/23/[$LATEST]",
    "functionName": "SignUpValidation",
    "memoryLimitInMB": "128",
    "functionVersion": "$LATEST"
  }
]