こんにちは!
最近は AmplifySDK を使用して認証周りを実装するケースが増えてきました。 AmplifySDK を使用することで、従来の amazon-cognito-identity-jsSDK よりも、よりシンプル・エレガントに認証処理実装を実現できます。
本記事では、AmplifySDK と NuxtJS・TypeScript を使用した認証処理の実装を解説します! NextJS(ReactJS)でも応用できる内容となっておりますので、 Amplify による認証処理実装をされたい方には必見です!
本記事は AmplifyCLI、または自前の Cloudformation などで構築されている Cognito を対象にした認証実装方法の紹介となります。
結論、プロトタイピングや PoC 的な開発をされたい場合は AmplifySDK によるインフラ構築をぜひ採用してみてください!逆に、長期的に開発していくアプリケーション開発で AmplifyCLI を採用しインフラ構築を行うのは、制約に苦しめられる可能性が高いのでご注意ください。
私たちは、長期的にアプリケーションを開発・保守していくケースが多いため、通常 AmplifyCLI ではなく、Cloudformation を書いてインフラを構築することが多いです。
├── plugins
│ └── amplify.ts Amplifyの設定プラグイン(nuxt.config.jsで読み込み設定)
│
├──middleware
│ └── authenticated.ts 認証状態必須ミドルウェア
│ └── notAuthenticated.ts 非認証状態必須ミドルウェア
│
├──services
│ └── authService.ts 認証サービス
Amplify の認証エンドポイント(Cognito)の設定を行います。nuxt.config.js
のplugins
に Amplify 設定用プラグインファイルを指定し、NuxtJS の Vue インスタンス生成前に読み込むようにします。尚、Amplify に設定する各種エンドポイントの設定値は、nuxt.config.js
のpublicRuntimeConfig
から取得するようにします。(Nuxt2.13 以降ならプロジェクトルートディレクトリの.env
がpublicRuntimeConfig
へバインドされます)
export default {
...
publicRuntimeConfig: {
REGION: process.env.REGION,
COGNITO_USER_POOL_ID: process.env.COGNITO_USER_POOL_ID,
COGNITO_USER_POOL_WEB_CLIENT_ID: process.env.COGNITO_USER_POOL_WEB_CLIENT_ID
},
plugins: [
{ src: '@/plugins/amplify.ts', mode: 'client' },
],
...
}
REGION={your_aws_region}
COGNITO_USER_POOL_ID={your_cognito_userpool_id}
COGNITO_USER_POOL_WEB_CLIENT_ID={your_cognito_client_id}
import Amplify from 'aws-amplify'
import { Plugin } from '@nuxt/types'
const myPlugin: Plugin = (context, inject) => {
Amplify.configure({
Auth: {
region: context.nuxtState.config.REGION,
userPoolId: context.nuxtState.config.COGNITO_USER_POOL_ID,
userPoolWebClientId:
context.nuxtState.config.COGNITO_USER_POOL_WEB_CLIENT_ID,
}
})
}
export default myPlugin
認証処理を扱うサービスファイルを作成します。本記事では触れませんが、サービス層には単体テストを実行し、動作を保証させておくことを推奨いたします。
import { Auth } from 'aws-amplify'
export const getUserId = async (): Promise<string> => {
const user = await Auth.currentAuthenticatedUser()
return user.attributes.sub
}
export const isAuthenticated = async (): Promise<boolean> => {
return await new Promise((resolve, reject) => {
Auth.currentAuthenticatedUser()
.then(() => resolve(true))
.catch(() => resolve(false))
})
}
認証状態を要するページ(例えば会員マイページ)に設定するミドルウェアです。
import { Context, Middleware } from '@nuxt/types'
import { getUserId, isAuthenticated } from '~/services/authService'
const myMiddleware: Middleware = async (context: Context) => {
const { store, redirect } = context
const _isAuthenticated = await isAuthenticated()
const promise: Promise<Function>[] = []
// 非認証の場合はログインページへリダイレクト
if (!_isAuthenticated) return redirect('/login')
// 認証済みの場合はユーザー情報取得系のStoreをディスパッチ
if (_isAuthenticated && store.getters['user/getUser'] === null)
promise.push(
store.dispatch('user/getUserById', {
Id: await getUserId(),
})
)
await Promise.all(promise)
}
export default myMiddleware
ログインページをはじめとした、非認証状態時に表示させたくないページに設定するミドルウェアです。
import { Context, Middleware } from '@nuxt/types'
import { isAuthenticated } from '~/services/authService'
const myMiddleware: Middleware = async (context: Context) => {
const { redirect } = context
// 認証状態必須ミドルウェアでStoreの取得処理はされるのでここでは実行しない
if (await isAuthenticated()) redirect('/home')
}
export default myMiddleware
本記事では、NuxtJS&TypeScript でよく使用される認証系ミドルウェアの実装を紹介しましたが、ReactJS で実装しているケースでも、Amplify の処理部分などをきっと応用できるはずです!この機会に Amplify で一歩進んだ認証実装にチャレンジしてみてください。
TypeScript フロントエンド開発のご相談は、お気軽にお問い合わせください。
スモールスタート開発支援、サーバーレス・NoSQLのことなら
ラーゲイトまでご相談ください
低コスト、サーバーレスの
モダナイズ開発をご検討なら
下請け対応可能
Sler企業様からの依頼も歓迎