SvelteKit + Luciaで簡単な認証を見てみる
#svelte #sveltekit #lucia #nodejs #備忘 #開発
SvelteKitを使って何かしらのWebサービスなり、それらの管理用Webアプリを作ろうとしたけど、
認証のところで何度も躓いた
んで調べてると、公式にこれがいいよーってのが見つかった
Auth • Docs • Svelte
Lucia
これを使ってログインを実装してみる
プロジェクトのセットアップ
$ npx sv create
Need to install the following packages:
sv@0.6.23
Ok to proceed? (y) y
┌ Welcome to the Svelte CLI! (v0.6.23)
│
◇ Where would you like your project to be created?
│ sveltekit-lucia-login
│
◇ Which template would you like?
│ SvelteKit minimal
│
◇ Add type checking with Typescript?
│ Yes, using Typescript syntax
│
◆ Project created
│
◇ What would you like to add to your project? (use arrow keys / space bar)
│ vitest, lucia
│
◇ The lucia add-on requires drizzle to also be setup. Include it?
│ Yes
│
◇ lucia: Do you want to include a demo? (includes a login/register page)
│ Yes
│
◆ drizzle: Which database would you like to use?
│ ● PostgreSQL
│ ○ MySQL
│ ○ SQLite
└
What would you like to add to your project? (use arrow keys / space bar)
でluciaを選ぶまではOKやったんやけど、
同時に必要なdrizzleを入れてもいい?ってなって、まあ必要ならOKってやってると、
drizzleがPostgreSQLかMySQLか、SQLiteが必要ってなってまってくれと、
drizzle自体が何なのかを先に調べたい
drizzleとは
Drizzle ORM - next gen TypeScript ORM.
ORMっぽい
RDB向けのORMやから、選択肢がRDBしかないのかー
さくっと実装したいならSQLiteが良いと思うけど、ファイルベースのsession管理とか、
他のDBを使えないかちょっと調べてみたい
drizzle以外の選択肢は?
Mongoose adapter · Lucia
mongodbのORMっぽいライブラリとしてmongooseがあるけど、それが対応しているっぽい
Getting started · Lucia
他にもいくつかのadapterが並んでる
改めまして
他の選択肢もあることを確認しましたが、用意されている選択肢からしか選べない感じっぽい
じゃあsession関連だけSQLiteにして、サービス本体で持ちたい情報は他の方法で扱うのがいいかも
ってことで、SQLiteでやってみましょう
$ npx sv create sveltekit-lucia-login
┌ Welcome to the Svelte CLI! (v0.6.23)
│
◇ Directory not empty. Continue?
│ Yes
│
◇ Which template would you like?
│ SvelteKit minimal
│
◇ Add type checking with Typescript?
│ Yes, using Typescript syntax
│
◆ Project created
│
◇ What would you like to add to your project? (use arrow keys / space bar)
│ vitest, lucia
│
◇ The lucia add-on requires drizzle to also be setup. Include it?
│ Yes
│
◇ lucia: Do you want to include a demo? (includes a login/register page)
│ Yes
│
◇ drizzle: Which database would you like to use?
│ SQLite
│
◇ drizzle: Which SQLite client would you like to use?
│ libSQL
│
◆ Successfully setup add-ons
│
◇ Which package manager do you want to install dependencies with?
│ npm
│
◆ Successfully installed dependencies
│
◇ Project next steps ─────────────────────────────────────────────────────╮
│ │
│ 1: cd sveltekit-lucia-login │
│ 2: git init && git add -A && git commit -m "Initial commit" (optional) │
│ 3: npm run dev -- --open │
│ │
│ To close the dev server, hit Ctrl-C │
│ │
│ Stuck? Visit us at https://svelte.dev/chat │
│ │
├──────────────────────────────────────────────────────────────────────────╯
│
◇ Add-on next steps ──────────────────────────────────────────────────╮
│ │
│ lucia: │
│ - Run npm run db:push to update your database schema │
│ - Visit /demo/lucia route to view the demo │
│ │
│ drizzle: │
│ - You will need to set DATABASE_URL in your production environment │
│ - Check DATABASE_URL in .env and adjust it to your needs │
│ - Run npm run db:push to update your database schema │
│ │
├──────────────────────────────────────────────────────────────────────╯
│
└ You're all set!
いくつかセットアップが必要そう
drizzleのためのDATABASE_URLを.envに書く
デフォルトで DATABASE_URL=file:local.db があるので、そのままでいけそう
マイグレーションの実行
$ npm run db:push
このSQL投げるけどいい?って聞かれるので、OKって返す
./local.db が作られているはず
このまま動作確認
$ npm run dev
http://localhost:5173/demo にアクセス
/demo/lucia にジャンプしたところ、認証情報がないため /demo/lucia/login に飛ばされる
最初はユーザーがないのでRegisterで登録
登録後は自動でログインされるが、ログアウトしたり再ログインしたりして動作を試せる
すごい動くぞ!!!
ざっと流れを確認しておく
src/hooks.server.ts
cookieからsessionTokenを取り出して、なかったらuserやsessionの情報をnullにしてリクエスト先の処理に移る
ログインしていない場合に表示したくないページ側でリダイレクトしてるんだと思われる
sessionTokenがあれば、それを利用してDBのsessionテーブルから該当sessionを取り出す
もし見つからなかったらsessionもuserもnullにして返し、リクエスト先の処理に移る
見つかったとしても、有効期限が切れていたらsessionもuserもnullにして返し、リクエスト先の処理に移る
見つかってかつ有効期限切れでなければ、取得したsessionとuserを返す
この時、有効期限まで15日未満なら、現在から30日後まで有効期限を延ばす
src/routes/demo/lucia/+page.server.ts
/demo/lucia にアクセスしたときに、 load 関数が叩かれる
もしuserが渡されていなければ = ログインできていなければ、 /demo/lucia/login にリダイレクト
ログインできていれば +page.svelte の中身を表示する
また、logoutされた場合の挙動もここに書かれてる
未ログイン状態なら401エラー
そうでなければsessionを無効にして、cookieからもsessionTokenを消して終わり
src/demo/lucia/login/+page.server.ts
/demo/lucia/login にアクセスしたおt機に、load関数が叩かれる
ログインしていたら /demo/lucia にリダイレクト
つまり、ログインしていたらログインページには行かせないって感じ
login画面でログインされたら、有効なusernameか、有効なpasswordかをチェックし、
問題なければDBに問い合わせて該当ユーザーが存在するかをチェック
居なかったり、パスワードが一致しなければ失敗
認証で問題がなければsessionをDBに登録して、cookieにsessionTokenを入れて /demo/lucia にリダイレクト
ざーっと確認するとこんな感じ
これくらいなら自前で実装できるそうで、ファイルベースで実装することも出来そうに感じるなー
次はluciaを参考にファイルベースsessionの認証を実装してみよう
更新履歴
2025/03/01 かきおわり
2025/02/28 かきはじめ