この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
Cognito のユーザー認証基盤!
AWS Summit 2016 Chicago にて Amazon Cognito の新機能「User Pools」が発表されました!! 本日 (2016/04/21) より Public Beta がご利用いただけます。
これまで Cognito の認証には Amazon や Google、Facebook、Twitter またはカスタムプロバイダ (自前) のアカウントが使用できましたが、 User Pools では Cognito がユーザーアカウントの基盤を持ち、アカウント登録やサインアップなどといった機能をマネージドに提供してくれます。 AWS らしいスケール可能で安全なユーザー認証基盤を簡単に構築することができます。
User Pool の作成
User Pool の作成は Cognito の Management Console から行えます。または AWS CLI の create-user-pool
を実行する方法なども既に提供されています。
ということで早速作ってみましょう。まずは Manage your user identities を選び Create new pool を選びます。
ここからは、これから作成する User Pool の設定を行います。まずは名前。
次は Attributes です。これは、ユーザー情報としてどのような属性値を付けるか決める設定です。 Required に付けるとアカウント登録時に設定が必須になります。ここに表示されている他に Custom Attribute も作成可能です。
次は Policies です。ここでは、ユーザーのパスワードのルールを決めます。最小何文字か、最大何文字か、数字や英字の組み合わせが必須か、などといった細かいポリシーを設定できます。
次は Verifications です。ここでは、アカウント登録しているユーザーへの MFA (他要素認証) に関する設定が行えます。必須ではありませんが、採用した方がセキュアにサインインさせることができます。 MFA には 電話番号またはメールによる認証が行えます。
次は Apps です。ここでは、作成する User Pool にアクセスできるクライアントを複数設定できます。
次は Triggers です。ここでは、サインアップやサインインなどが行われたときに呼び出す、任意の Lambda Function を設定できます。
次のようなイベントをフックできます。
ライフサイクル | 説明 |
---|---|
Pre sign-up | サインアップのリクエストが送られたときに呼ばれる。独自のバリデートを挟むことも可能。 |
Custom message | 認証または MFA のメッセージを送信する前に呼ばれる。メッセージを動的に作成可能。 |
Pre authentication | サインインのリクエストが送られたときに呼ばれる。IP 縛りなどのようなバリデートを挟むことが可能。 |
Post authentication | サインインが完了したときに呼ばれる。ログやアナリティクスへの送信などの処理を挟むことが可能。 |
Post confirmation | ユーザーの登録が完了したときに呼ばれる。ログやアナリティクスへの送信などの処理を挟むことが可能。 |
以上で User Pool の作成が終わりました! Pool Id が発行されています。
Apps を見てみると、ClientID と ClientSecret が発行されています。
iOS アプリから使う
上記で作成した User Pool を利用して iOS アプリでサインアップやサインインを行ってみましょう。
Xcode プロジェクトを適当に作成しまして、CocoaPods 経由で AWS SDK for iOS をインポートします。
Podfile
source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '9.0'
target 'YOUR_APP_NAME' do
pod 'AWSCore'
pod 'AWSCognitoIdentityProvider'
end
pod install
でインポートは終わりです。
AWSCognitoIdentityUserPool オブジェクトの生成
iOS アプリで User Pool にアクセスするには AWSCognitoIdentityUserPool オブジェクト経由で行います。AWSCognitoIdentityUserPool の登録は、次のコードのように行います。AppDelegate クラスに書いておくと良いでしょう。
#import <AWSCognitoIdentityProvider/AWSCognitoIdentityProvider.h>
#import "AppDelegate.h"
@implementation AppDelegate
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// AWSServiceConfiguration には CredentialsProvider は渡さない
AWSServiceConfiguration *configuration = [[AWSServiceConfiguration alloc] initWithRegion:AWSRegionUSEast1 credentialsProvider:nil];
[AWSServiceManager defaultServiceManager].defaultServiceConfiguration = configuration;
// Register しておく
AWSCognitoIdentityUserPoolConfiguration *userPoolConfiguration = [[AWSCognitoIdentityUserPoolConfiguration alloc] initWithClientId:@"CLIENT_ID"
clientSecret:@"CLIENT_SECRET"
poolId:@"USER_POOL_ID"];
[AWSCognitoIdentityUserPool registerCognitoIdentityUserPoolWithUserPoolConfiguration:userPoolConfiguration
forKey:@"AmazonCognitoIdentityProvider"];
return YES;
}
@end
registerCognitoIdentityUserPoolWithUserPoolConfiguration:
メソッドで登録しておくことで、キーである AmazonCognitoIdentityProvider
を渡せばどこでも AWSCognitoIdentityUserPool オブジェクトにアクセスできるようになります。例えば、下記は ViewController から取得した場合です。
#import "ViewController.h"
#import <AWSCognitoIdentityProvider/AWSCognitoIdentityProvider.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
AWSCognitoIdentityUserPool * pool = [AWSCognitoIdentityUserPool CognitoIdentityUserPoolForKey:@"AmazonCognitoIdentityProvider"];
// ...任意の API を呼ぶことができる
}
@end
あとはこの AWSCognitoIdentityUserPool オブジェクトを使って、サインアップやサインインを行うことができます。ドキュメントに記載されている一通りの機能の実装方法を紹介します。
サインアップ
サインアップにはユーザー名とパスワード、そして認証に使うメールアドレスや電話番号を設定します。メールアドレスと電話番号が必要かどうかは User Pool を作成した時の設定値に依ります。
AWSCognitoIdentityUserAttributeType * phone = [AWSCognitoIdentityUserAttributeType new];
phone.name = @"phone_number";
phone.value = @"+15555555555";
AWSCognitoIdentityUserAttributeType * email = [AWSCognitoIdentityUserAttributeType new];
email.name = @"email";
email.value = @"email@mydomain.com";
//sign up the user
[[pool signUp:@"username" password:@"password" userAttributes:@[email,phone] validationData:nil] continueWithBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUser *> * _Nonnull task) {
if (task.error) {
} else {
AWSCognitoIdentityUser * user = task.result;
//need to confirm user using user.confirmUser:
}
return nil;
}];
電話番号を使う場合は、上記処理を実行すると SMS が届きます。
ここで受け取った認証コードを confirmSignUp:
メソッドで渡すと認証が成功し、アカウントが有効になります!
AWSCognitoIdentityUser *user = [pool getUser:@"username"];
[[user confirmSignUp:@"xxxxxx"] continueWithBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserConfirmSignUpResponse *> * _Nonnull task) {
if (task.error) {
NSLog(@"%@", task.error);
} else {
NSLog(@"%@", task.result);
}
return nil;
}];
Management Console で確認してみると Confirmed になっていることが確認できます。
ユーザーの取得
ユーザーを取得するには、幾つかの方法が用意されています。
//get the last logged in user
[pool currentUser];
//get a user without a username
[pool getUser];
//get a user with a specific username
[pool getUser:@"username"];
ユーザー属性の検証
[[user getAttributeVerificationCode:@"phone_number"] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserGetAttributeVerificationCodeResponse *> * _Nonnull task) {
//success
return nil;
}];
[[user verifyAttribute:@"phone_number"code:@"code"] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserVerifyAttributeResponse *> * _Nonnull task) {
//success
return nil;
}];
サインイン
[user getSession:@"username" password:@"password" validationData:nil scopes:nil];
パスワードリセット
[[user forgotPassword] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserForgotPasswordResponse*> * _Nonnull task) {
//success
return nil;
}];
[[user confirmForgotPassword:@"code" password:@"newPassword"] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserConfirmForgotPasswordResponse *> * _Nonnull task) {
//success
return nil;
}];
ユーザー属性の取得
[[user getDetails] continueWithBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserGetDetailsResponse *> * _Nonnull task) {
if (task.error) {
} else {
AWSCognitoIdentityUserGetDetailsResponse *response = task.result;
//do something with response.userAttributes
}
return nil;
}];
ユーザー属性の更新
AWSCognitoIdentityUserAttributeType * attribute = [AWSCognitoIdentityUserAttributeType new];
attribute.name = @"name";
attribute.value = @"John User";
[[user updateAttributes:@[attribute]] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserUpdateAttributesResponse *> * _Nonnull task) {
//success
return nil;
}];
パスワードの変更
[[user changePassword:@"currentPassword" proposedPassword:@"proposedPassword"] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserChangePasswordResponse *> * _Nonnull task) {
//success
return nil;
}];
MFA の有効化
AWSCognitoIdentityUserSettings * settings = [AWSCognitoIdentityUserSettings new];
AWSCognitoIdentityUserMFAOption * mfaOptions = [AWSCognitoIdentityUserMFAOption new];
mfaOptions.attributeName = @"phone_number";
mfaOptions.deliveryMedium = AWSCognitoIdentityProviderDeliveryMediumTypeSms;
settings.mfaOptions = @[mfaOptions];
[[user setUserSettings:settings] continueWithSuccessBlock:^id _Nullable(AWSTask<AWSCognitoIdentityUserSetUserSettingsResponse *> * _Nonnull task) {
//success
return nil;
}];
まとめ
Cognito を使う上で一番の課題だったユーザー登録機能が、ついに AWS から提供されました。実用的な機能をより簡単に構築できるため、これを使わない手はないです。まずは触ってみてください!
まだ掘り下げきれていない内容もあるので、別な記事でご紹介したいと思います!