UnityでCognito UserPoolsを使ってサインアップ・サインインを実現する
開発環境のセットアップ
検証に先立ち、以下の開発環境を構築しました。
- macOS 10.13.4
- Unity 2017.2.2f1
- Mono 5.4.1.6
Unityプロジェクトの作成とAWS SDK導入
UnityではC#とUnity Scriptを使えますが、今回はC#を使います。
AWS Mobile SDK for Unityは執筆時点でCognito UserPoolsに対応していないため、今回はAWS SKD for .NETを使用します。これはNuGetで配布されているので、UnityでのNuGetパッケージ管理ツールとして、Nuget for Unityを使用します。
アセットストアからダウンロードして、プロジェクトにインポートします。
また、AWS SDK for .NETはMicrosoft .NET Framework 3.5 以降を必須要件としていますが、Unity 2017はデフォルトが2系を使うランタイム設定なので、Experimentalに変更して4系に変更する必要があります。
※ 次期バージョンのUnity 2018からデフォルトのランタイムが.NET 4.6になるそうです。 https://blogs.unity3d.com/jp/2018/01/05/discontinuing-support-for-monodevelop-unity-starting-in-unity-2018-1/
ここまで設定したら、NuGet for Unityを使ってAWS SDK for .NETを導入します。NuGet > Manage NuGet Packagesで検索フォームに "Cognito" と検索して、以下のパッケージをプロジェクトに追加します。
- Amazon Cognito Identity Provider
- CognitoAuthentication
インストールが終了すると、以下のようにAWS SDK Coreもインストールされているはずですが、されていない場合は手動でインストールしてください。
CognitoAuthenticationは、Extension Libraryと呼ばれているもので、現在はDeveloper Previewとなっている公式ライブラリです。詳細は以下のリンク先を参照してください。
https://aws.amazon.com/jp/blogs/developer/cognitoauthentication-extension-library-developer-preview/
Cognito UserPools設定
Unity側で指定する項目として、Cognito UserPools作成時に発行されるIDが必要です。今回はus-west-2に作成しました。emailをusernameとして使う設定にします。
その後、Client Idを作成します。詳細は割愛します。
Unityアプリ
Unityを操作して、以下のような画面を作成します。
そして、各ボタンに以下のようなスクリプトを設定します。
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using Amazon; using Amazon.CognitoIdentityProvider; using Amazon.CognitoIdentityProvider.Model; public class Signup : MonoBehaviour { public InputField emailField; public InputField passwordField; static string clientId = "0123456789abcdef"; void Start () { } void Update () { } public void OnClick() { var client = new AmazonCognitoIdentityProviderClient (null, RegionEndpoint.USWest2); var sr = new SignUpRequest (); string email = emailField.text; string password = passwordField.text; sr.ClientId = clientId; sr.Username = email; sr.Password = password; sr.UserAttributes = new List<AttributeType> { new AttributeType { Name = "email", Value = email } }; try { SignUpResponse result = client.SignUp(sr); Debug.Log(result); } catch (Exception ex) { Debug.Log (ex); } } }
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using Amazon; using Amazon.CognitoIdentityProvider; using Amazon.CognitoIdentityProvider.Model; public class Confirmation : MonoBehaviour { public InputField emailField; public InputField confirmationCodeField; static string clientId = "0123456789abcdef"; void Start () { } void Update () { } public void OnClick(){ var client = new AmazonCognitoIdentityProviderClient (null, RegionEndpoint.USWest2); ConfirmSignUpRequest confirmSignUpRequest = new ConfirmSignUpRequest(); confirmSignUpRequest.Username = emailField.text; confirmSignUpRequest.ConfirmationCode = confirmationCodeField.text; confirmSignUpRequest.ClientId = clientId; try { ConfirmSignUpResponse confirmSignUpResult = client.ConfirmSignUp(confirmSignUpRequest); Debug.Log(confirmSignUpResult.ToString()); } catch (Exception ex) { Debug.Log(ex); } } }
using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; using Amazon; using Amazon.Runtime; using Amazon.CognitoIdentityProvider; using Amazon.Extensions.CognitoAuthentication; public class Signin : MonoBehaviour { public InputField emailField; public InputField passwordField; static string clientId = "0123456789abcdef"; static string userPoolId = "us-west-2_0123ABCD"; void Start () { } void Update () { } public void OnClick() { Debug.Log("Start Signup"); try { AuthenticateWithSrpAsync(); } catch(Exception ex) { Debug.Log(ex); } } public async void AuthenticateWithSrpAsync() { var provider = new AmazonCognitoIdentityProviderClient (null, RegionEndpoint.USWest2); CognitoUserPool userPool = new CognitoUserPool( userPoolId, clientId, provider ); CognitoUser user = new CognitoUser( emailField.text, clientId, userPool, provider ); AuthFlowResponse context = await user.StartWithSrpAuthAsync(new InitiateSrpAuthRequest(){ Password = passwordField.text }).ConfigureAwait(false); Debug.Log(user.SessionTokens.IdToken); } }
動作確認
メールアドレスとパスワードを入力してサインアップすると、メールアドレスにconfirmation codeが届きます。
それを入力すると、IdTokenとしてJWTを得られます。デコードすると以下のようになります。
{ "sub": "aaaa1111-abcd-aa11-bb22-0123abcd", "aud": "0123456789abcdef", "email_verified": true, "event_id": "fbb432a5-3b90-11e8-bc39-4f741e568ae0", "token_use": "id", "auth_time": 1523235452, "iss": "https://cognito-idp.us-west-2.amazonaws.com/us-west-2_0123ABCD", "cognito:username": "0c08e593-f9f8-4b51-XXXX-XXXXXXXX", "exp": 1523239052, "iat": 1523235452, "email": "example@example.com" }
まとめ
このエントリでは、Cognito UserPoolsを使ったUnityアプリのサインインとサインアップを実装しました。
次回は、今回入手した認証情報を使ったリクエストを実装します。
4/12追記 第二回はこちらです