serverless framework 第2回 cognito のセットアップ
はじめに
記事についての
こちらの記事は連載企画の第2弾です!
cognitoによる認証を試していきます!
予定記事
- セットアップ&チュートリアル
- cognito を利用した認証機能の作成 <-- 現在
- dynamodb を利用した CRUD の作成
- serverless-offline を利用したローカル環境の作成
- 応用的な使い方(cognito を利用した authorizer の作成)
cognito を利用した認証機能の作成
今回の手順
- serverless framework を利用した cognito のセットアップ
- ユーザの作成・認証テスト
- トリガーの使い方
serverless.yml を利用した cognito のセットアップ
cognito のセットアップに利用するプロジェクトを作成します
今回は最小限の構成で cognito をセットアップします
# 以下を追記
resources:
Resources:
CognitoUserPool:
Type: AWS::Cognito::UserPool
Properties:
UserPoolName: ${self:app}-user-pool # 任意の名前を指定
CognitoUserPoolClient:
Type: AWS::Cognito::UserPoolClient
Properties:
UserPoolId:
Ref: CognitoUserPool
ExplicitAuthFlows:
- ALLOW_USER_PASSWORD_AUTH # パスワード認証に必要
- ALLOW_USER_SRP_AUTH # SDKによる認証に必要
- ALLOW_REFRESH_TOKEN_AUTH # RefreshTokenによる認証に必要
デプロイ
serverless deploy
AWS consoleよりユーザープールが作成されていることを確認します
ユーザープールを選択し、プール ID とアプリクライアント ID を控えておきます
ユーザの作成・認証テスト
コンソール上でユーザの作成・認証ができることを確認していきます
ユーザ登録の確認
Username が Email となっていることに注意してください
Cognito では認証に使用するユニークな値を Username として利用するようになっています
curl https://cognito-idp.us-east-1.amazonaws.com \
-XPOST \
-H 'X-Amz-Target: AWSCognitoIdentityProviderService.SignUp' \
-H 'Content-Type: application/x-amz-json-1.1' \
-d '{"ClientId": [アプリクライアントID], "Username": "test@example.com", "Password": "Test1234!" }'
{
"ClientId": [アプリクライアントID],
"Username": "test@example.com",
"Password": "Test1234!"
}
- レスポンスがエラーでなければユーザが追加されているはずなので
aws console
上で確認を行います
- アカウントのステータスが
UNCONFIRMED
となっているのでユーザを選択してユーザの有効化を行います
- ユーザーの有効化を行うとステータスが
CONFIRMED
に変更されます
パスワードによる認証確認
このパスワードによる認証確認のために ALLOW_USER_PASSWORD_AUTH
のオプションが必要になります。
curl https://cognito-idp.us-east-1.amazonaws.com \
-XPOST \
-H 'X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth' \
-H 'Content-Type: application/x-amz-json-1.1' \
-d '{"ClientId": [アプリクライアントID], "AuthFlow": "USER_PASSWORD_AUTH", "AuthParameters": { "USERNAME": "test@example.com", "PASSWORD": "Test1234!" }}'
{
"ClientId": [アプリクライアントID],
"AuthFlow": "USER_PASSWORD_AUTH",
"AuthParameters": {
"USERNAME": "test@example.com",
"PASSWORD": "Test1234!"
}
}
リクエストが成功すると以下のようなレスポンスがあるのでRefreshToken
を控えます
次のリフレッシュトークンでの認証に使用します
{
"AuthenticationResult": {
"AccessToken": "...",
"ExpiresIn": 3600,
"IdToken": "...",
"RefreshToken": "...", // <== これを控える
"TokenType": "Bearer"
},
"ChallengeParameters": {}
}
リフレッシュトークンでの認証
先ほど控えた RefreshToken
を利用してセッションを確認します
curl https://cognito-idp.us-east-1.amazonaws.com \
-XPOST \
-H 'X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth' \
-H 'Content-Type: application/x-amz-json-1.1' \
-d '{"ClientId": "6q13el38vb7pppet579747bidf", "AuthFlow": "REFRESH_TOKEN_AUTH","AuthParameters": { "REFRESH_TOKEN": [リフレッシュトークン]"}}'
パスワードによる認証確認と同じレスポンスがあれば OK です
{
"ClientId": [アプリクライアントID],
"AuthFlow": "REFRESH_TOKEN_AUTH",
"AuthParameters": {
"REFRESH_TOKEN": [リフレッシュトークン]
}
}
SDK による React への導入をしてみたのでこちらのリポジトリも確認してみてください
React への導入サンプル 『https://github.com/naok1207/react-cognito-auth』
トリガーについて
cognito ではトリガーという概念があり、AWS Lambda 関数を使用して認証のカスタマイズをすることができます。
今回は試しにユーザー登録時にユーザの有効化を自動で行えるようにしてみます。(現状では先ほど行ったように一度 AWS Console 上で有効化をする必要があります)
- トリガー用の関数を作ります
handler.js
に追記
module.exports.preSignUp = async (event, _context, callback) => {
event.response.autoConfirmUser = true;
callback(null, event);
};
- 関数のデプロイを行います
serverless.yml
に追記
functions:
...
# 追記
preSignUp:
handler: handler.preSignUp
events:
- cognitoUserPool:
pool: ${self:app}-user-pool # 任意に指定したUserPoolName
trigger: PreSignUp # トリガーの名前
existing: true # 作成済みのユーザープールを利用する
デプロイ
serverless deploy
この状態で先ほど行った『ユーザ登録の確認』を再度実行すると最初からCONFIRMED
となっていることが確認できるはずです。
このようにトリガー関数を利用して認証をカスタマイズすることができます。
以上で cognito を利用した認証機能の作成 は終了とします。
追記
UserPool
とUserPoolClient
のオプションを調べたので追記しておきます
UserPool のオプションについて
## プロパティ全体
Type: AWS::Cognito::UserPool
Properties:
# ユーザがパスワードを忘れた際のリカバリ設定
AccountRecoverySetting: AccountRecoverySetting
# 管理者にのみユーザーの作成を許可するか、ユーザーに自己サインアップを許可するかの設定(デフォルトでは自己サインアップが許可される) in policy
AdminCreateUserConfig: AdminCreateUserConfig
# ユーザープールのエイリアスの設定
AliasAttributes:
- String # phone_number, email, preferred_username
# 自動で検証される属性の設定
AutoVerifiedAttributes:
- String # email, phone_number
# デバイスを記録するための設定 よりセキュアなシステムを構築する際に使用
DeviceConfiguration: DeviceConfiguration
# 認証関連に利用するEmailの設定
EmailConfiguration: EmailConfiguration # (デフォルト COGNITO_DEFAULT 使用上限あり)
# MFA認証の有効設定
EnabledMfas:
- String
# トリガーの設定 functions内部でも行える
LambdaConfig: LambdaConfig
# MFA認証の対象者の設定
MfaConfiguration: String
# ポリシーの設定 (主にパスワードポリシーの設定)
Policies: Policies
# ユーザープールのスキーマ設定
Schema:
- SchemaAttribute
# SMS認証で表示するメッセージ
SmsAuthenticationMessage: String
# SMSの設定
SmsConfiguration: SmsConfiguration
# emailや電話番号の変更に関する設定
UserAttributeUpdateSettings: UserAttributeUpdateSettings
# ユーザー名に使用する属性の設定
UsernameAttributes:
- String # phone_number or email
# 大文字と小文字の区別を行うかどうかの設定
UsernameConfiguration: UsernameConfiguration
# 高度なセキュリティモードの有効化設定 IPアドレスの制限などができるみたい?
UserPoolAddOns: UserPoolAddOns
# ユーザープールの名前の設定
UserPoolName: String
# ユーザープールを分類するために利用するタグの設定
UserPoolTags: Json
# 様々な確認メッセージのテンプレートの設定
VerificationMessageTemplate: VerificationMessageTemplate
詳しくは
UserPoolClient のオプションについて
後程追記します。
詳しくは
参考
会社の紹介
株式会社mofmofでは一緒に働いてくれるエンジニアを募集しています。
興味のある方は是非こちらのページよりお越しください!
次回は『dynamodbを利用したCRUDの作成』を予定しています。
Discussion