Cognitoの認証機能を簡単にsetupしつつ、webクライアント(js)からユーザ登録、ログイン、ログアウト、パス忘れに対応するお試し実装。
この実装フローではCognitoのWebコンソールを直接触らない。
前提
- 2018.11.14現在
- yarn
1.10.1
https://yarnpkg.com/ja/ - 要AWSアカウント
- 用語ざっくり
-
Mobile Hub
モバイルアプリやwebサービス開発で使えるAWSサービスを簡易にセットアップ出来るサービス(Mobile Hub自体は無料、他サービスは別途) -
Cognito
ユーザ認証とAWSへのアクセスコントロールを行うサービス(月間アクティブ50,000まで無料) -
Amplify
AWSの新しいライブラリ、Cognito等を簡易に利用できるよう作られたもの。- 公式docではグローバルインストールしたamplifyから
amplify configure
をすることでMobile Hubのセットアップをしつつappプロジェクトの作成が出来るような記述があるが、今回は使わない。 - この記事は
aws-amplify-1.1.10
aws-amplify-vue-0.1.7
を使用。
- 公式docではグローバルインストールしたamplifyから
-
CognitoのUser Pool, ID Poolについて(読み飛ばしてok)
- 公式図解(一例)
-
User Pool
は認証プロバイダ。ユーザ登録やログインの提供をする -
ID Pool(フェデレイテッドアイデンティティ)
は認証プロバイダを束ね、AWSリソースへのアクセス権限のコントロール等を行う。 - 2種類のソーシャルログイン連携方法
-
User Pool
は一つの認証プロバイダであり、Facebook等他のソーシャルログイン系もそれぞれ認証プロバイダとして、ID Pool
で統括することが出来る。(ID Poolでの連携) - ややこしいのが、
User Pool
内でも、Facebook等ソーシャルログイン系認証プロバイダを組み込む事ができる。(User Poolでの連携) - 上記2つは別物。
-
- ユーザ登録、ログイン、パス忘れ等のユーザ登録認証のみを利用する場合、
ID Pool
は使われない。(が、Analyticsのためか、Mobile Hubで勝手に作られてaws-exportsにID Pool IDがセットされるため、そこはかとなく利用されている)
構築フロー
- AWS マネジメントコンソールでMobile HubからCognitoの設定をして
app-config.zip
をダウンロードする - サンプル用Nuxtプロジェクトをセットアップする
- プロジェクトにAmplifyのコードを入れて確認する
1. AWS マネジメントコンソールでMobile HubからCognitoの設定をしてapp-config.zip
をダウンロードする
- コンソールからMobile Hubの新しいプロジェクトを作る
-
Create a project
...プロジェクト名はこの例ではcognito-test
。リージョンをここで変更できるのでチェックする -
Select app platform
...プラットフォームはWeb
を選ぶ。今回はweb hostingは使わないのでチェックを外す
-
Set up your backend
、Connect to your backend
は説明だけなのでそのまま進める。 - 作成したプロジェクトが表示(下図)されるので、ページ下の方へ行き
User sign-in
を選択。
- 下図のように
User sign-in
のセットアップをする(Email or phone numberを選択すれば、必須項目でそれらをチェックする必要なし)
- 上図で
Create user pool
後、プロジェクト(cognito-test
)のApps > Backend features
のIntegrate
を選択 -
Update your backend
画面(下図)が出るので、Download Cloud Config
から設定をDL
-
app-config.zip
がダウンロードされ、解答するとaws-config.js
とaws-exports.js
があるはず。configはaws-sdk-js(旧ライブラリ)の設定ファイル(多分)で、exportsはamplify-js(新ライブラリ)の設定ファイル。使うのはexportsの方。
2. サンプル用Nuxtプロジェクトをセットアップする
- Nuxtプロジェクト
cognito-test
を作る。Mobile Hubのプロジェクト名と同名である必要はない。
# あれこれsetupの情報を聞かれるがよしなに。
$ yarn create nuxt-app cognito-test
# プロジェクトディレクトリに移動
$ cd cognito-test
# 初期インストール(必要ないかも)
$ yarn
# 開発ローカルサーバ立ち上げ
$ yarn dev
-
http://localhost:3000
にアクセスしてNuxtのスタートアップ画面が表示されるのを確認
3. プロジェクトにAmplifyのコードを入れて確認する
amplifyの追加インストール
# すでにyarn devしてたら一度Ctrl+Cで切って、必要なパッケージをインストール
$ yarn add aws-amplify aws-amplify-vue
# その後、再度ローカルサーバ起動
$ yarn dev
設定ファイルaws-exports.jsの配置
- ダウンロードしたファイルを適当に配置(たとえばプロジェクトroot)
$ cp ~/Download/aws-config/aws-exports.js ~path/to/cognito-test/
AmplifyセットアップのNuxtプラグインを追加
plugins/amplify.js
import Vue from 'vue'
import Amplify, * as AmplifyModules from 'aws-amplify'
import { AmplifyPlugin, components } from 'aws-amplify-vue'
import aws_exports from '../aws-exports'
Amplify.configure(aws_exports)
Vue.use(AmplifyPlugin, AmplifyModules)
Vue.component(components)
Nuxtのconfigでプラグイン読み込み
nuxt.config.js
- plugins: [],
+ plugins: [{ src: '~/plugins/amplify.js', ssr: false }],
- amplifyを使うのは認証のためなので、認証先のページではSSRの必要が無い想定。
index.vueトップページの書き換え
pages/index.vue
<template>
<section class="container">
<div>
<logo/>
<no-ssr>
<amplify-authenticator :auth-config="authConfig"/>
<amplify-sign-out/>
</no-ssr>
</div>
</section>
</template>
<script>
import Logo from '~/components/Logo.vue'
export default {
components: {
Logo
},
data() {
return {
authConfig: {
// 通常のログイン
signInConfig: {
header: 'Sign in !!'
},
// 登録
signUpConfig: {
hideDefaults: true,
signUpFields: [
{ label: 'Email', key: 'username', required: true, type: 'email', displayOrder: 0 },
{ label: 'Password', key: 'password', required: true, type: 'text', displayOrder: 1 }
]
},
// 登録confirm
confirmSignUpConfig: {},
// パス忘れ
forgotPasswordConfig: {},
// MFA
confirmSignInConfig: {}
}
}
}
}
</script>
ブラウザで確認
-
http://localhost:3000
で上記の様なページが表示されれば成功 - Create accountでユーザ仮登録(そのページで今度は検証コードが入力出来るようになるので、メールの検証コードを入力して本登録完了)
- 本登録したらSign in出来るようになる
- Forgot passwordも、ユーザ登録と同じフロー
- フォームに表示される
Username
とはEmailのこと。(これはMobile HubでのUser sign-inでEmailでサインイン出来るように設定しているため)
このあと(未検証)
フォームのカスタマイズ
- 本例だとEmailがUsernameと表示されちゃうとか、検証コード入力が画面残しとかないと入力できないとか、フォームデザインのカスタマイズとかする場合は、用意された
<amplify-authenticator>
等のComponentを使わず、jsで開発する。 - https://aws-amplify.github.io/docs/js/authentication
検証コード記載メールにワンタイムtoken付きのURLを載せる
- https://ap-northeast-1.console.aws.amazon.com/cognito/users
- Cognito User Pool画面から、
[対象のプロジェクト] > 全般設定 > メッセージのカスタマイズ
から変更する 公式doc
検証メールの送信元(From, ReplyTo)の変更
- https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/cognito-user-pool-settings-email-address-customization.html
- https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/cognito-user-pool-settings-ses-authorization-to-send-email.html
ソーシャルログインの追加
- 上述の通り、User Poolで連携する方法とID Poolに連携する方法がある。
- User Pool
- 各ソーシャルログインプロバイダでのCognito用の設定と、awsコンソールでソーシャルログインプロバイダの情報を設定
- https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/cognito-user-pools-identity-federation.html
- ID Poolの連携
- 各ソーシャルプロバイダのSDKを使って自前で認証してそのトークンを設定したID Poolにわたす
- https://docs.aws.amazon.com/ja_jp/cognito/latest/developerguide/external-identity-providers.html
- ユーザに直接AWSリソースを触らせず、ユーザ登録・認証のみを使う様な場合、ID Poolには出来るだけ触れずに、User Poolでやった方が良いように思う。が、現在のところUser Poolはtwitter認証ないのでそれが必要なら、ID Poolで頑張る感じになるのかも。(か、FirebaseとかAuth0を使うとか)
- Amplifyでのソーシャルログイン実装は未検証。公式docではID Poolを使うぽく書いてあるが、実際はUser Poolを使ってる?みたいな記述もある。
- とりあえずAWSのドキュメントに従えば、指定URLに飛ばせばUser Poolでの認証フローになるはずなので、twitterが必要なければ、User Poolのみで対応できそう。
認証情報の取り回し
index.vue
<script>
+ import { Auth } from 'aws-amplify'
export default {
// ... 省略
+ mounted() {
+ Auth.currentAuthenticatedUser()
+ .then(user => {
+ console.log(user.username)
+ console.log(user.signInUserSession.accessToken.payload.sub)
+ console.log(user)
+ })
+ .catch(err => console.log(err))
+ }
}
</script>
- これでログインしてページリロードとかすると、認証したユーザ情報がconsole上に表示される
-
Auth.currentAuthenticatedUser()
やAuth.currentSession()
を使うと取れるaccessToken.jwtToken
をAPIバックエンドサーバ等に投げて、検証すれば、自サーバ上でも認証の確認が出来る。 - refreshTokenによるrefreshはAmplifyが自動でやってくれる。(ただしGoogle/Facebook以外のソーシャルログイン・あとAmplifyを使わないソーシャルログインとかはやってくれなそう)
Cognito User Poolのアプリクライアントが2つ作られる
projectname_userpoolapp_MOBILEHUB_00000 web
projectname_userpoolapp_MOBILEHUB_00000
- の様に2種類のアプリクライアントがUser Pool上に作られるが、これはクライアントシークレットの有り無しだと思われる。webで使う方はクライアントシークレットの生成をしていないものを使う。もう一つは使い所不明。バックエンドとかからアクセスする用?
所感
- amplify自体が発展途上な感じがするが、ソーシャルログインを考えなければ実装コストはFirebase Authenticationと変わらない。
- jsならvueよりもReactの方ができること多そう。
- 無料枠も申し分ないし、ソーシャルログインを考えなければいい感じ。
- Cognitoはやっぱり魔境でプロダクトレベルで使うのはまだまだ勉強が足りないと思った。