この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
前回の記事の続きです。
今回はUserPoolsにサインアップして、AWS側で認証したユーザーを確認するまでを行います。
API GatewayとCognito UserPoolsを連携する
事前に、Cognito UserPoolsを作成します。 前回の記事でCognito UserPoolsのUserPoolを作成しているので、追加で以下の操作を行います。
以下の操作のドキュメントはこちらを参照してください。
API GatewayでResourceとMethodを作成
リソース名としては良くないですが、今回はGET /authorize
を作成しました。
API Gateway Authorizerを作成
マネジメントコンソールのAPIs > Authorizers > Create New Authorizer
から、UserPoolsを指定してAuthorizerを作成しました。
Authorization Headerを見るので、Token SourceにはAuthorization
と記入します。
Method RequestのAuthorizationにAuthorizerを指定
以下の点に気をつけて指定します。
- Authorizationには、先ほど作成したAPI Gateway Authorizerを指定する
- OAuth ScopeはNONEのままにしておく
Request Validatorはデフォルトのままでも良いのですが、ValidationすることでAuthorization HeaderがないリクエストではLambdaを起動しない挙動になり、セキュリティの実装とコスト削減を手軽に実現できます。
この設定をする場合は、Method RequestのHTTP Request HeadersにAuthorizationを追加し、Requiredに設定します。
Integration RequestでLambda Proxyを設定
このあとUserPoolsのUser NameをsubとしてLambda Functionのevent objectで受け取れることを確認するので、Lambda Proxyを設定します。
事前に以下のようなLambda Functionを作成します。詳細は割愛します。
import json
import logging
logger = logging.getLogger()
logger.setLevel(logging.INFO)
def lambda_handler(event, context):
logger.info(event)
return {
'statusCode': 200,
'body': json.dumps({'message': 'success'}, ensure_ascii=False),
'headers': {'Content-Type': 'application/json'}
}
ここまでやったらStageにDeployします。
DeployしたAPIをUserPoolsのApp IntegrationでResource Serverに設定する
ドキュメントはこちらです。 https://docs.aws.amazon.com/ja_jp/apigateway/latest/developerguide/apigateway-create-cognito-user-pool.html
- Nameは適当に入力します
- Identifierは、StageにDeployされたAPI Gateway APIに付与されるURLを記載します。Custom Domainを設定している場合はそちらを設定します。
Unity側のソースコードを変更する
前回のサンプルアプリを修正します。画面は以下の画像のようにしました。
サインアップとConfirmation Codeのスクリプトは前回の記事と一緒です。
サインイン
サインインも前回とやってることは一緒なのですが、APIの動作確認を楽にするためにIdTokenを自動でGETリクエストのフォームに入力するようにしました。
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;
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;
public InputField tokenField;
static string clientId = "MyClientId";
static string userPoolId = "us-west-2_xxxxxxx";
void Start () {
}
void Update () {
}
public void OnClick() {
Debug.Log("Start Signin");
try {
CallAuthenticateTask();
} catch(Exception ex) {
Debug.Log(ex);
}
}
private async void CallAuthenticateTask() {
var context = SynchronizationContext.Current;
AuthFlowResponse response = await AuthenticateWithSrpAsync();
context.Post((state) => {
tokenField.text = response.AuthenticationResult.IdToken;
}, null);
}
private async Task<AuthFlowResponse> AuthenticateWithSrpAsync() {
var provider = new AmazonCognitoIdentityProviderClient (null, RegionEndpoint.USWest2);
CognitoUserPool userPool = new CognitoUserPool(
userPoolId,
clientId,
provider
);
CognitoUser user = new CognitoUser(
emailField.text,
clientId,
userPool,
provider
);
return await user.StartWithSrpAuthAsync(new InitiateSrpAuthRequest(){
Password = passwordField.text
}).ConfigureAwait(false);
}
}
Authorization Header付きGETリクエスト
詳細はUnityのドキュメントを参照してください。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using UnityEngine.Networking;
public class GetRequest : MonoBehaviour {
public InputField tokenField;
// API Gatewayが作成して、Resource Serverにも指定したURL
static string url = "https://api-gw-published-url/authorize";
void Start () {
}
void Update () {
}
public void OnClick () {
StartCoroutine(GetText());
}
IEnumerator GetText() {
string token = tokenField.text; // UserPoolsから取得したIdToken
UnityWebRequest www = UnityWebRequest.Get(url);
www.SetRequestHeader("Authorization", token); // Authorization Headerの付与
yield return www.SendWebRequest();
if (www.isNetworkError || www.isHttpError) {
Debug.Log(www);
} else {
Debug.Log(www.downloadHandler.text);
}
}
}
動作確認
Lambdaのlogger.info(event)
がCloudWatch Logsに出力されています。サインアップしたユーザーの情報が取得できていることがわかります。
{..., 'headers': {..., 'Authorization': 'eyJra...vqA', ..., 'requestContext': {..., 'authorizer': {'claims': {'sub': '0c08e593-f9f8-aaaa-bbbb-ccccccc', 'aud': '
まとめ
前回の記事に引き続き、Cognito UserPoolsとAPI Gatewayの連携を設定して、UnityアプリからAuthorization Header付きでHTTPリクエストを送り、クラウド側でUserPoolsが発行するUser IDをLambda Functiondで取得しました。