AWSの認定は保有していますが
実践できていない主なサービスがサーバレスまわり…
ということで勉強を兼ねて、簡単なAPIを作成してみます。
#やりたいこと
APIでユーザ作成
- ログイン名 と パスワードをリクエストボディに指定しAPIをコールするだけでユーザ作成する。
- メールアドレス/電話番号の認証は不要。
#やってみよう!
###ユーザプールの作成
こんな私でもCognitoでユーザ管理をするにはユーザプールを作成しなければならないことは知っている。
認証フローはよくわからないため全てチェック。※今後勉強します
ALLOW_USER_PASSWORD_AUTH が絶対必要
「クライアントシークレットを作成」にはチェックを入れないこと。
###Lambda用IAMロール
Lambdaの基本的なポリシーに加えて、「AmazonCognitoPowerUser」をアタッチする。
###ユーザ作成用のLambdaを作成
今回、ソースコード内のアプリクライアントID,ユーザプールIDはLambdaの環境変数にセットしています。
作成するユーザはすぐに使える状態にしたかったので、adminConfirmSignUpを利用して確認済み(CONFIRMED)のステータスに変更しています。
バリデーションやエラー処理は適当なので、適宜変更をお願いします。
'use strict';
const AWS = require('aws-sdk');
const cognito = new AWS.CognitoIdentityServiceProvider();
/**
* SignUp
*/
exports.handler = async (event, context) => {
const response = {};
let loginName;
let password;
console.log(event);
// Validation
if (!(event.body) || !('loginName' in JSON.parse(event.body)) || !('password' in JSON.parse(event.body))) {
response["statusCode"] = 400;
return response;
} else {
let reqestBody = JSON.parse(event.body);
loginName = reqestBody["loginName"];
password = reqestBody["password"];
}
// SignUp parameters
const params = {
ClientId: process.env['APP_CLIENT_ID'],
Username: loginName,
Password: password
};
response["headers"] = {"Access-Control-Allow-Origin" : "*", "Content-Type" : "application/json"};
// SignUp
try {
const user = await cognito.signUp(params).promise();
console.log('User sign up success!!!', JSON.stringify(user, null, 4));
const confirmParams = {};
confirmParams['UserPoolId'] = process.env['USER_POOL_ID'];
confirmParams['Username'] = loginName;
const result = await cognito.adminConfirmSignUp(confirmParams).promise();
console.log('result : ' + JSON.stringify(result));
response["statusCode"] = 201;
response["body"] = JSON.stringify({"loginName" : loginName});
return response;
}
catch(err) {
console.log('User sign up failed...' + err);
if (err.code == 'UsernameExistsException') {
response["statusCode"] = 409;
} else if (err.code == 'InvalidPasswordException') {
response["statusCode"] = 400;
} else {
response["statusCode"] = 500;
}
return response;
}
};
ユーザプールにユーザが作成された。
ステータスもCONFIRMEDになっている。めでたい!
API Gatewayの作成
「Lambdaプロキシの統合」にチェックを入れ、作成したLambda関数を選択する。
その後、メールアドレスや電話番号が指定された場合はその値をCognitoに登録するソースへ編集しました。
'use strict';
const AWS = require('aws-sdk');
const cognito = new AWS.CognitoIdentityServiceProvider();
/**
* SignUp
*/
exports.handler = async (event, context) => {
const response = {};
let loginName;
let password;
let userAttributes;
console.log(event);
// Validation
if (!(event.body) || !('loginName' in JSON.parse(event.body)) || !('password' in JSON.parse(event.body))) {
response["statusCode"] = 400;
return response;
} else {
let reqestBody = JSON.parse(event.body);
loginName = reqestBody["loginName"];
password = reqestBody["password"];
userAttributes =[];
if('email' in JSON.parse(event.body)) {
userAttributes.push({'Name':'email','Value':reqestBody["email"]});
}
if('phone' in JSON.parse(event.body)) {
userAttributes.push({'Name':'phone_number','Value':reqestBody["phone"]});
}
}
// SignUp parameters
const params = {
ClientId: process.env['APP_CLIENT_ID'],
Username: loginName,
Password: password,
UserAttributes:userAttributes
};
response["headers"] = {"Access-Control-Allow-Origin" : "*", "Content-Type" : "application/json"};
// SignUp
try {
const user = await cognito.signUp(params).promise();
console.log('User sign up success!!!', JSON.stringify(user, null, 4));
const confirmParams = {};
confirmParams['UserPoolId'] = process.env['USER_POOL_ID'];
confirmParams['Username'] = loginName;
const result = await cognito.adminConfirmSignUp(confirmParams).promise();
console.log('result : ' + JSON.stringify(result));
response["statusCode"] = 201;
response["body"] = JSON.stringify({"loginName" : loginName});
return response;
}
catch(err) {
console.log('User sign up failed...' + err);
if (err.code == 'UsernameExistsException') {
response["statusCode"] = 409;
} else if (err.code == 'InvalidPasswordException') {
response["statusCode"] = 400;
} else {
response["statusCode"] = 500;
}
return response;
}
};
#感想
とりあえず動くものはできたので一安心。
サインアップは出来たけど確認済みへのステータス変更でエラーになった場合にはリトライで再チャレンジなのか…?
ロールバックがないので工夫は必要である。
#今後の宿題
- APIでユーザ認証をし、アクセストークンを取得する
- APIでユーザ情報を取得する