ログインの実装 (Svelte & Lucia)
このコードは、SvelteKitのサーバーサイド機能を活用して、ユーザーログインの処理を行うものです。Luciaを使用してセッション管理を行い、認証の流れを実装しています。
+page.server.ts
: ログイン処理とリダイレクト
load
関数: セッションの検証とリダイレクト
import type { Actions } from "@sveltejs/kit";
import { auth } from "$lib/server/lucia";
import { fail, redirect } from "@sveltejs/kit";
import type { PageServerLoad } from "./$types";
export const load = (async ({ locals }) => {
const session = await locals.auth.validate();
if (!session) {
return {};
}
redirect(303, "/");
}) satisfies PageServerLoad;
解説
locals.auth.validate()
を使い、現在のセッションが有効かを確認。- セッションがない場合
{}
を返してログインページを表示。 - セッションが有効なら
redirect(303, "/")
でトップページへ遷移。 satisfies PageServerLoad;
を使用し、型の安全性を確保。
actions
オブジェクト: ログイン処理
export const actions = {
login: async ({ request, locals }) => {
const { username, password } = Object.fromEntries(
await request.formData()
) as {
username: string;
password: string;
};
try {
const key = await auth.useKey("username", username, password);
const session = await auth.createSession({
userId: key.userId,
attributes: {},
});
console.log(session);
locals.auth.setSession(session);
} catch (error) {
console.error(error);
return fail(400, { message: "The username or password is incorrect." });
}
redirect(303, "/");
},
} satisfies Actions;
解説
request.formData()
からusername
とpassword
を取得。auth.useKey("username", username, password)
でユーザー認証を実行。- 認証成功時:
auth.createSession()
でセッションを作成。locals.auth.setSession(session)
でセッションを設定。redirect(303, "/")
でトップページへ遷移。
- 認証失敗時:
fail(400, { message: "The username or password is incorrect." })
を返し、エラーメッセージを表示。
+page.svelte
: ログインフォームとエラーメッセージの表示
<script lang="ts">
import { enhance } from "$app/forms";
import type { ActionData } from "./$types";
export let form: ActionData;
</script>
解説
enhance
を$app/forms
からインポートし、フォーム送信を最適化。form
はサーバーから返されるActionData
型のエラーメッセージを格納。
<form
class="bg-white shadow-md rounded-lg max-w-sm mx-auto mt-20 p-6"
use:enhance
action="?/login"
method="post"
>
use:enhance
でフォーム送信を最適化。action="?/login"
でactions.login
にフォームを送信。method="post"
でPOSTリクエストを送信。
<input type="text" id="username" name="username" required />
<input type="password" id="password" name="password" required />
username
とpassword
の入力フィールドを作成。required
属性で入力必須。
{#if form?.message}
<div class="mt-4 p-3 bg-red-100 text-red-700 rounded-lg">{form.message}</div>
{/if}
form?.message
がエラー時に表示される。
<p>Don't have an account? <a href="/signup">Register here.</a></p>
- まだアカウントを持っていないユーザー向けの登録リンク。
まとめ
load
関数でセッションを確認し、ログイン済みならリダイレクト。actions.login
でユーザー認証を処理し、エラー時には適切なメッセージを表示。- ページ側のフォームでは
use:enhance
を活用し、動的なエラーメッセージを表示。 redirect(303, "/")
でログイン成功後にトップページへ遷移。