概要
Amplifyで認証を入れたときのメモ。
バックエンドサーバーの構築,ローカルでのテスト
amplify authの設定
以下を参考に,認証を組み込んでいきます。https://docs.amplify.aws/javascript/build-a-backend/auth/add-social-provider/
amplify add auth
以下のようにサインアウト・サインインの後のリダイレクト先を設定する項目があります。とりあえずはローカルで動かすとして,localhostを設定しておきます。(Amplifyでホスティングするときには修正が必要になります。)
...
? Enter your redirect signin URI:
`http://localhost:3000/`
? Enter your redirect signout URI:
`http://localhost:3000/`
ひとしきりの質問に答えることで,Amplifyの構成ファイルがローカルに作成されます。これを以下コマンドでAWSに送信します。
amplify push
このコマンドを叩くと裏でCloudFormationが動きます。構成が完了すると,以下のようなエンドポイントが表示されます。
Hosted UI Endpoint: https://{アプリ名とランダムな文字列}-dev.auth.{region}.amazoncognito.com
このURLをGCPの"APIとサービス">"認証情報">"OAuth 2.0 クライアント ID"の
"Authorized Javascript origin"に貼り付けます。
同様に"Authorized Redirect URIs"には,URLの末尾に/oauth2/idpresponse
をつけて貼り付けます。
ログインアプリの作成
以下のようなログイン・ログアウトだけのシンプルなコンポーネントを作成します。
import { Amplify } from 'aws-amplify';
import { Authenticator, AccountSettings } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';
import awsmobile from '../src/aws-exports.js';
Amplify.configure(awsmobile);
const LoginBoard = () => {
const handleSuccess = () => {
alert('user has been successfully deleted')
}
return (
<>
<Authenticator socialProviders={['google']}>
{({ signOut, user }) => (
<main>
<button onClick={signOut} className='underline'>
サインアウト
</button>
<div>
<>
ここにログインユーザーにしか見えないコンテンツを入れる
</>
<AccountSettings.DeleteUser />
</div>
</main>
)}
</Authenticator>
</>
)
}
export default LoginBoard
重要なのは以下の部分です。
import awsmobile from '../src/aws-exports.js';
Amplify.configure(awsmobile);
aws-exports.jsというファイルにcognitoの認証情報が書き込まれており,これをもとにしてAmplifyに構成ファイルを渡します。そうすると,Authenticator
, AccountSettings
などのコンポーネントが認証の確認先を認識することができるようになります。
ローカルでの動作チェック
yarn dev
でテストサーバーを立てて,試しにGoogleサインインしてみます。
ログイン前
ログイン後
ログインできていれば,Cognitoのユーザープールにユーザーが追加されているのが確認できます。
"DeleteUser"のボタンでアカウント削除も可能です。
Amplifyでのホスティング
ビルド
amplifyにgithubのブランチを登録します。
バックエンド環境を選ぶところは,先ほど作ったバックエンドの名前を差すようにします。サービスロールはamplifyconsole-backend-role
を選択します。
自動でブランチの内容を読み取って,サーバーのビルド設定amplify.yml
を生成してくれます。自分の環境だととりあえずこのままでもビルドが通りました。
version: 1
backend:
phases:
build:
commands:
- '# Execute Amplify CLI with the helper script'
- amplifyPush --simple
frontend:
phases:
preBuild:
commands:
- yarn install
build:
commands:
- yarn run build
artifacts:
baseDirectory: .next
files:
- '**/*'
cache:
paths:
- .next/cache/**/*
- node_modules/**/*
backend側でamplifyPush --simple
と書いているのがミソになっています。
立ち上がった直後のサーバーはgithubからコードをcloneしただけの状態で,cognitoなどのサービスとの接続情報を持っていません。そのため,amplifyPush
コマンドが必要になります。
実行するとビルドが始まり,サーバーの更新が完了するまで待ちます。完了するとAmplifyが以下のようなURLを発行してくれるので,サイトにアクセスできます。
https://{ブランチ名}.{ランダムな文字列}.amplifyapp.com/
サイト内の静的ページには問題なくアクセスできますが,Google認証しようとするとエラーが出て失敗します。
エラー対応
userpoolにリダイレクトURLを追加する
先ほどはリダイレクトURLにlocalhostだけを設定していましたが,発行されたURLを追加します。
ついでに,特定のドメインを取得している場合はそれも追加します。
amplify auth update
以下のように聞かれるところで,リダイレクトURLを編集するように答えます。
What do you want to do?
>Add/Edit signin and signout redirect URIs
...
# 以下を追加する。
https://www.example.com/ # カスタムドメイン
https://{ブランチ名}.{ランダムな文字列}.amplifyapp.com/ # amplifyで生成されたURL
カスタムドメインは当初https://example.com/
を入れていたのですが,www
をつけないとエラーが出るようでした。
リダイレクト先を環境により書き換える
loginboard.tsx
を編集します。
以下のように,awsmobile
のredirectSignIn
またはredirectSignOut
を実行環境によって書き換えるようにします。
// 環境によってリダイレクト先を変更
if (typeof window !== "undefined") {
awsmobile.oauth.redirectSignIn = `${window.location.origin}/`;
awsmobile.oauth.redirectSignOut = `${window.location.origin}/`;
}
Amplify.configure(awsmobile);
備考
ログインユーザーの権限
amplify authをpushした際に,amplify... authRole
,またはamplify... unauthRole
というIAMロールが作成されています。authRoleがログインユーザーのロール,unauthRoleがゲストユーザーに与えられている権限になります。
この辺りの情報はAWS内のリソースに対してAPIを実行する際に重要になります。