【ワンピースで覚えるNuxt】ミドルウェア/ログイン機能
認証情報の保存
useCookie
クッキーオブジェクトはリアクティブな変数
export interface Character {
id: number;
name: string;
bounty: number;
}
export interface ReturnJSONCharacters {
result: number;
data: Character[];
}
export interface User {
id: number;
name: string;
loginId: string;
password: string;
}
//ログインユーザサーバAPIエンドポイント
//レスポンスオブジェクト
export interface ReturnJSONAuth {
result: number;
token: string;//認証が通らなかった場合空文字
user: User | null;//認証が通らなかった場合null
}
server/routes/user-management/auth.post.ts
import type { User, ReturnJSONAuth } from "@/interfaces";
export default defineEventHandler(
async (event): Promise<ReturnJSONAuth> => {
//レスポンスオブジェクトの各プロパティの初期値を用意。
let resultVal = 0;
let tokenVal = "";
let loginUser: User|null = null;
try{
// throw createError("擬似エラー発生。");
//リクエストボディを取得。
const body = await readBody(event);
//この時点でエンドポイント側の処理は成功とみなす。
resultVal = 1;
//ログインIDとパスワードが正しければ…
if(body.loginId == "onepiece" && body.password == "bounty") {
//アクセストークンを生成。
tokenVal = "abcabcabcabcab";
//ログインユーザ情報を格納。
loginUser = {
id: 1,
name: "尾田栄一郎",
loginId: body.loginId,
password: ""
}
}
}
//エラー処理。
catch(err) {
console.log(err);
}
//レスポンスオブジェクトをリターン。
return {
result: resultVal,
token: tokenVal,
user: loginUser
};
}
);
pages/login.vue
<script setup lang="ts">
import type {User} from "@/interfaces";
//ログイン入力コントール用テンプレート変数。
const loginId = ref("");
//パスワード入力コントール用テンプレート変数。
const password = ref("");
//ペンディング(読込中)かどうかを表すテンプレート変数。
const pending = ref(false);
//エンドポイント側でエラーがないことを表すテンプレート変数。
const noServerError = ref(true);
//認証が失敗したことを表すテンプレート変数。
const authFailed = ref(false);
//ログインボタンクリック時の処理メソッド。
const onLoginButtonClick = async (): Promise<void> => {
//ペンディングをtrueに変更。
pending.value = true;
//authFailedを初期値に変更。
authFailed.value = false;
//noServerErrorを初期値に変更。
noServerError.value = true;
//ログインデータのPOST送信。
const asyncData = await useFetch(
"/user-management/auth",
{
method: "POST",
body: {
loginId: loginId.value,
password: password.value
}
}
);
//エンドポイント側の処理が成功したならば…
if(asyncData.error.value == null && asyncData.data.value != null && asyncData.data.value.result == 1) {
//認証が通ったならば…
if(asyncData.data.value.token != "" && asyncData.data.value.user != null) {
//ログインユーザ情報をクッキーに格納。
const loginUserCookie = useCookie<User|null>("loginUser");
loginUserCookie.value = asyncData.data.value.user;
//アクセストークン文字列をクッキーに格納。
const loginTokenCookie = useCookie<string|null>("loginToken");
loginTokenCookie.value = asyncData.data.value.token;
//トップ画面に遷移
await navigateTo("/");
}//認証が通らなかった場合…
else {
pending.value = false;
authFailed.value = true;
}
} //エンドポイント側の処理が失敗した場合…
else {
pending.value = false;
noServerError.value = false;
}
};
</script>
<template>
<h1>ログイン</h1>
<p v-if="pending">ログイン中…</p>
<template v-else>
<p v-if="authFailed">ログインIDまたはパスワードが違います。</p>
<p v-if="noServerError">IDとパスワードを入力してログインしてください。</p>
<p v-else>サーバ処理中に障害発生!もう一度ログインを行なってください。</p>
<form v-on:submit.prevent="onLoginButtonClick">
<dl>
<dt>ID</dt>
<dd><input type="text" v-model="loginId" required></dd>
<dt>パスワード</dt>
<dd><input type="password" v-model="password" required></dd>
</dl>
<button type="submit">ログイン</button>
</form>
</template>
</template>
pages/logout.vue
<script setup lang="ts">
import type {User} from "@/interfaces";
//ログインユーザ情報のクッキーを削除。
const loginUserCookie = useCookie<User|null>("loginUser");
loginUserCookie.value = null;
//アクセストークン文字列のクッキーを削除。
const loginTokenCookie = useCookie<string|null>("loginToken");
loginTokenCookie.value = null;
//ログイン画面に遷移。
await navigateTo("/login");
</script>
components/TheLoggedInSection.vue
<script setup lang="ts">
import type {User} from "@/interfaces";
const loginUser = useCookie<User|null>("loginUser");
</script>
<template>
<section v-if="loginUser">
<p>{{loginUser.name}}さんがログイン中</p>
<p><NuxtLink v-bind:to="{name: 'logout'}">ログアウト</NuxtLink></p>
</section>
</template>
layouts/character.vue
<template>
<header>
<h1>ワンピース!</h1>
</header>
<main>
<h1>キャラクター設定</h1>
<TheLoggedInSection/>
<slot/>
</main>
</template>
ここから先は
2,901字
¥ 100
この記事が気に入ったらサポートをしてみませんか?