前説
AWS AmplifyUI+Vueでユーザー認証してみる(前編)。の続き記事になります。
前編では、Amplifyのプロジェクトを新規作成し、ユーザー認証のUIコンポーネントを追加してみる所まで行いました。
今回の記事では、その情報を参考に、既存のVueプロジェクトにユーザー認証用のAmplifyUIコンポーネントを適用する所まで行います。
AmplifyUIコンポーネント導入に必要な内容確認
まず、前編の記事で、AmplifyUIを追加した事で発生した変化を確認します。
増えたファイルは以下の2つです。こちらはAmplifyプロジェクトとしての情報を保持している様です。
- amplify/backend/auth/myamplifyproject*********/cli-inputs.json
- amplify/backend/backend-config.json
認証関係の情報が追加されたのは以下のファイルです。
- amplify/backend/types/amplify-dependent-resources-ref.d.ts
- amplify/team-provider-info.json
App.vueに以下の部分が追加されました。
<script setup>
import { Authenticator } from '@aws-amplify/ui-vue';
import '@aws-amplify/ui-vue/styles.css';
</script>
既存プロジェクトはAmplifyのプロジェクトではないので、4ファイルに関してはそのまま追加は出来なさそうです。情報としては認証に使われるcognitoのIDなどが記載されています。まとめると以下の対応になりそうです。
- モジュールのインポート
- 認証用に使われるcognitoの情報設定
これらのキーワードで検索していると、オフィシャルのページにそのままの情報がありました。
実対応
実際に適用していきます。
Vue3へ移行
上記ページには下記メッセージがあります。Vue2ではGoogleアカウントなどのソーシャルログインとの連携があまり考慮されてない過去のコンポーネントしか使えなさそうです。
これはこれで大きな話題ですが、今回の件と本質的には関係無いのでまたの機会にします。
簡単に言うと、Vue3の新規プロジェクトを作成し、使っていたrouterやelement-uiなどモジュールをVue3用に替え、既存ソースを順次移植する方法を採用しています。記事を書いている時点では、初期表示するページだけ移行している状況です。
モジュールのインポート
公式ページ通りです。
yarn add @aws-amplify/ui-vue aws-amplify
認証用に使われるcognitoの情報設定
Login部分に使用するVueファイルでは以下の記載が必要です。ここが設定する部分です。
import awsconfig from './aws-exports';
Amplify.configure(awsconfig);
前編の記事ではaws-exports.jsというファイルがあり、それはAmplifyが自動的に更新する設定ファイルという事が解っています。それをもとに、Amplify.configureを実行して情報をセットする必要があります。
公式ページや、それを実際に使用している記事がありました。実際に使用されている記事からすると、公式ページのScoped configuration
を行っておけば大丈夫そうです。前編の記事で生成されていたのはTop level configuration
の様です。
export default {
Auth: {
// (required) only for Federated Authentication - Amazon Cognito Identity Pool ID
identityPoolId: 'XX-XXXX-X:XXXXXXXX-XXXX-1234-abcd-1234567890ab',
// (required)- Amazon Cognito Region
region: 'XX-XXXX-X',
// (optional) - Amazon Cognito User Pool ID
userPoolId: 'XX-XXXX-X_abcd1234',
// (optional) - Amazon Cognito Web Client ID (26-char alphanumeric string, App client secret needs to be disabled)
userPoolWebClientId: 'a1b2c3d4e5f6g7h8i9j0k1l2m3',
}
}
実際のアプリで使用
CognitoとAmplifyUIの導入が済んだ状態です。実際にアプリで使用していきます。大きく分けて2種類の仕様部分があります。
- ログイン処理
- トークンを使ってAPIアクセス
基本情報の取得
実際には、ログイン後に各コンポーネントでログイン情報を使用する必要があります。基本情報は公式ページにありました。
まず、useAuthenticatorを使ってauthオブジェクトを生成しています。
import { Authenticator, useAuthenticator } from '@aws-amplify/ui-vue';
const auth = useAuthenticator();
その後、auth.user
でユーザー情報を参照したり、auth.route
でログイン状況を取得できます。
<template v-if="auth.route === 'authenticated'">
<h1>Hello {{ auth.user?.username }}!</h1>
<button @click="auth.signOut">Sign out</button>
</template>
ログイン処理
サンプルを真似て、ログイン成功まではログイン画面のみを表示し、成功したらrouterを表示する形にします。
<template>
<authenticator>
<template v-slot="{ signOut }">
<button @click="signOut">Sign Out</button>
</template>
</authenticator>
<div id="app">
<div v-if="auth.route === 'authenticated'">
<router-view/>
</div>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue';
import { Authenticator, useAuthenticator } from "@aws-amplify/ui-vue";
import { Amplify } from 'aws-amplify';
import "@aws-amplify/ui-vue/styles.css";
import awsconfig from '@/aws-exports';
Amplify.configure(awsconfig);
export default defineComponent({
setup() {
const auth = ref(useAuthenticator());
return {
auth
}
},
components: {
Authenticator
},
});
</script>
トークンを使ってAPIアクセス
今回AmplifyUI導入のアプリでは、APIアクセスで、APIGatewayでCognitoオーサライザーを使用しています。IDトークン内のjwtトークンをHeaderで渡す必要があります。
ログイン情報の取得
ユーザー情報はCognitoUserAmplifyクラスで取得出来そうです。
元ソースを見るとCognitoUser
の継承オブジェクトの様です。amazon-cognito-identity-js
からimportされています。
必要なプロパティは上記amazon-cognito-identity-jsがあるリポジトリを探せばよさそうです。サンプルで使っているusername
もあります。
トークンの取得
APIアクセスの時に、ヘッダーにjwtトークンを埋める必要があります。今までは、session.getIdToken().getJwtToken()
という関数を使っていました。
前述のCognitoUser.js
のリポジトリを見ると、getSessionにcallback関数をセットする様です。
そして、そのcallbackは最終的に(error,session)というパラメーターが渡されるようです。
そこからは同様にgetIdToken().getJwtToken()を使えそうです。この部分でthis.signInUserSession
を使っていますが、リフレッシュ処理などを考慮したsessionをgetSession
関数で取得するべきかと思います。
今回は、以下の様なモジュールを作成しました。
import axios from 'axios';
import { BalanceView } from '@/common/interfaces';
import masterdata from '@/const/masterdata';
import { useAuthenticator } from '@aws-amplify/ui-vue';
const API_BASE_URL = (process.env.VUE_APP_API_BASE_URL as string);
export default class ApiCalls {
// 共通して使用する関数
// eslint-disable-next-line @typescript-eslint/no-explicit-any
callGetApi = async (url: string, config: {[key:string]: any}, callback: any): Promise<any> => {
const auth = useAuthenticator();
auth.user.getSession(async (error: Error, session: CognitoUserSession) => {
if (error != null) {
throw error;
}
const addHeaders = {
'Content-Type': 'application/json',
'Authorization': `Bearer ${session.getIdToken().getJwtToken()}`
};
const newHeaders = config['headers'] ? {
...config['headers'],
...addHeaders
} : addHeaders;
const newConfig = {
...config,
'headers': newHeaders
}
const response = await axios.get(url, newConfig);
return callback(response);
});
};
// ビジネスロジック用関数での使用例
getBalanceList = async (tgtDate: string): Promise<BalanceView[]> => {
return new Promise(resolve => {
const url = `${API_BASE_URL}/balance?tgt_date=${tgtDate}`;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
this.callGetApi(url, { data: {}}, (response: any) => {
const wkBalanceList: BalanceView[] = [];
for (const resdata of response.data) {
const wkBalance: BalanceView = {
method_nm: masterdata.getMethodNm(resdata['method_cd']),
value_fmt: Number(resdata['value']).toLocaleString()
}
wkBalanceList.push(wkBalance);
}
resolve(wkBalanceList);
});
});
};
}
使用する側は以下の様な感じです。
const api = new ApiCalls();
// 中略
const balanceList = await api.getBalanceList(tgtToDateStr);
感想
通常、ログイン画面だけなら結構シンプルですが、ユーザー登録、パスワード変更画面など思いのほか実装が必要な画面があります。そこをパッケージングしてくれるこのAmplifyUIはすごく便利だと思いました。
今回はそのAmplifyUIをAmplifyプロジェクトでない通常のVueプロジェクトで使用してみました。Cognitoオーサライザーに対応しているAPIアクセスも出来ました。
Vue3への移行途中です。今回で技術的課題が無くなりました。これで安心して残りのVue3移行を進める事が出来ます。