API側でCognito認証してアプリ側でCognito認可してamplify
AWS Amplify はすごく便利だけど、レールから外れると難しい。
普通にやると、Cognitoで認証・認可して Pinpoint でPUSH通知が簡単にできる。
ただ、Cognitoの認証部分だけAPI Gateway経由で呼び出すようなシステム構成だと簡単ではない。
Cognitoの認証と認可
Cognitoは、「User Pool」と「Identify Pool」がある。
User Poolはアプリに対して認証を提供してくれて、Identify Poolはユーザーに対して認可を行うことができる。
認可することで、AWSリソースに対してIAM Roleに応じてユーザーがアクセスできる。
ちなみに、認可は認証しなくても使える。(認証済み or 未認証で Role を分けれる)
認証する場合は、User Pool や Facebook認証などを Provider として設定できる。
アプリで認証しない
システムの都合上、API Gateway を介して Cognito認証する必要があって、その場合は普通には出来ない。
aws-amplify/amplify-js では、アプリ側で Cognito認証を行ってそのまま認可まで行くことを想定しているので、
API経由で認証する場合は、自分でamplifyを認証状態にする必要がある。
その前に、ConsoleLoggerのLOG_LEVELをDEBUGにしておくと調査が捗る。
結構ログを出してくれているので、エラーが出たら、Githubでソースを検索して問題の処理を見てく感じで。
import {ConsoleLogger} from '@aws-amplify/core' ConsoleLogger.LOG_LEVEL = 'DEBUG'
前提になりますが、configureはこんな感じで。
今回は、インフラ構築にamplify cliは使ってないので、aws-exprots.jsは使ってない。
Amplify.configure({ Auth: { identityPoolId: 'ap-northeast-1:XXXX-XXXX-XXXX', userPoolId: 'ap-northeast-1_XXXXXXX', userPoolWebClientId: 'XXXXXXXXXXXXXXXX', region: 'ap-northeast-1', }, Analytics: { AWSPinpoint: { appId: 'XXXXXXXXXXXXXXXXXX', region: 'us-east-1', }, }, })
APIからのレスポンスで、Credentialsを設定する(認証状態にする)
import { CognitoUserSession, CognitoIdToken, CognitoAccessToken, CognitoRefreshToken, } from 'amazon-cognito-identity-js' import {Credentials} from '@aws-amplify/core' ... const {token} = result.payload const session = new CognitoUserSession({ IdToken: new CognitoIdToken({IdToken: token.idToken}), AccessToken: new CognitoAccessToken({AccessToken: token.accessToken}), RefreshToken: new CognitoRefreshToken({ RefreshToken: token.refreshToken, }), }) await Credentials.set(session, 'session') ...
これで、認証状態になるので、User Poolで認証してIdentify Poolで認証済みのRoleを持ったもので認可できる。
まあ、わかれば簡単なのだけど。
トラブルシューティング
Identify Poolの未認証と認証のRoleを逆に設定してしまって1日はまった :|