Lucia による認証

(2024-04-04)

Lucia による認証を実装したいと考えています。

とても難易度が高くて、ネット記事の情報では動くものは見つけられませんでした。

GitHub にサンプルがあったので、ダウンロードして実験してみました。

username-and-password のダウンロード

GitHub 上の username-and-password というプログラムを使用します。

https://github.com/lucia-auth/examples/tree/main/astro/username-and-password にあるのですが、それをダウンロードすることはできません。

そこで以下のようにして、examples 全体をダウンロードしました。

Terminal window
git clone https://github.com/lucia-auth/examples.git

ダウンロードされた examples の中の astro/username-and-password を使用します。

このフォルダを ~/ に置いて、

Terminal window
cd username-and-password

lucia パッケージをインストール。

Terminal window
yarn add lucia

サーバーを起動して、http://localhost:4321/ にアクセスすると、

lucia1

ユーザー名とパスワードを適当に入力してアカウントを保存。

ログインすると、

lucia2

なんだかすごいですね。

ログイン情報を sqlite3 に記録

デフォルトでは、src/lib/db.ts は、

export const db = sqlite(":memory:");

となっていて、メモリ上にデータベースが作成され、プログラムが終了すると情報が消失してしまうようなので、 ログイン情報を sqlite3 に保存するよう変更しました。

export const db = sqlite("./auth.sql3");

こうすると、ルートディレクトリに auth.sql3 が作成されてログイン情報が記録されます。

lucia3

Cannot read properties of undefined (reading ‘map’)

認証をかけたい astro ファイルの先頭に以下のようなコードを書くと、部分的なアクセス制限が実装できます。

---
const user = Astro.locals.user;
if (!user) {
return Astro.redirect("/login");
}
---

ああとても便利、と思ったのですが、タグ検索でエラーが出現します。

Cannot read properties of undefined (reading 'map')

どうも、[tag].astro の以下の部分が引っかかるようです。

{posts.map((post) => <BlogPost url={post.url} title={post.frontmatter.title}/>)}

現在の私の実力ではどうも解決はできないようで、ひょっとして lucia による部分的なアクセス制限とタグ検索が本質的に競合するのではないかと考えるようになりました。