😍

Lucia-authという認証ライブラリが良い感じ

2023/06/26に公開

Luciaとは

lucia v2についてきちんと書きます! (そのうち笑)

認証ライブラリ

必要最低限なAPIのみを提供してくれているので、柔軟に認証周りを書ける

この記事では、lucia v2 について扱う。v2はまだベータ版なので、APIは変更される可能性あり。

Please keep in mind that while there won’t be any further changes to the | > database schema, APIs are bound to change before the stable release.

v2ドキュメントはこちら
https://v2.lucia-auth.com/basics/keys

コードはこちら
https://github.com/pilcrowOnPaper/lucia

使ってみて良かったところ

(当たり前だけど)type-safe

以下はsveltekitの例だけど、こんな感じでセッションの中身、ユーザーの属性(名前とかメルアドとか)を定義する。

/// <reference types="lucia" />
declare global {
	namespace App {
		interface Locals {
			auth: import('lucia').AuthRequest;
		}
	}
}

/// <reference types="lucia" />
declare global {
	namespace Lucia {
		type Auth = import('$lib/server/auth/lucia').Auth;
		type DatabaseUserAttributes = {
			email: string;
			emailVerified: Date | null;
		};
		// eslint-disable-next-line @typescript-eslint/ban-types
		type DatabaseSessionAttributes = {
			createdAt: Date;
		};
	}
}

export {};

これでユーザー作成の時にもattributesに候補が出る

const user = await auth.createUser({
	key: {
		providerId: 'email',
		providerUserId: email,
		password
	},
	attributes: {
		email,
		emailVerified: null
	}
});

APIが柔軟

セッションを発行したり、ユーザーを作成したり必要最低限の独立性の高いAPIだから、Next-Authより自由度が高い。

Discordがある ・ examplesが豊富

何か困ったら質問できるし、examplesを見れば一通り実装できる

exampleはこちら↓
https://github.com/pilcrowOnPaper/lucia/tree/v2-examples/examples

キーとは

email や GitHub Google などのプロバイダーとユーザーの関係を表すもの。ユーザーは複数の認証方法を持つことができる。

Next-AuthでいうAccountテーブルみたいな感じ

password (オプション) は自動的にハッシュ化されて保存される。

元々 token integrationというのがあったけど、v2で廃止されたので、メルアド検証やパスワード忘れなどの基本的な機能は独自で実装することになる
この実装例も、examplesにある

以下はアバウトな実装手順の概要

メールアドレス検証

  1. アカウント登録したユーザーのメールアドレスが正しいか検証する
  2. 有効期限付きのトークンをユーザーIDと紐付けてDBに保存する
  3. `.../email-verification/[token]のようなリンクを記載したメールを送る
  4. トークンが正しくない / ユーザーが存在しない / ユーザーのメールアドレスがすでに検証されている場合はエラーを返す
  5. 全てのセッションを無効にし、メールアドレス検証フラグを更新、全てのメールアドレス検証トークンを削除する ( transaction )
  6. セッションを新しく作成する

パスワード忘れ

ユーザーがパスワードを忘れた場合に、メールアドレスを元に新しいパスワードを設定できるようにしたい

  1. 有効期限付きのトークンをユーザーIDと紐付けてDBに保存する
    `.../reset-password/[token]のようなリンクを記載したメールを送る
  2. トークンが正しくない / ユーザーが存在しない 場合はエラーを返す
  3. 全てのセッションを無効にし、パスワードを更新、全てのパスワード更新トークンを削除する ( transaction )
  4. セッションを新しく作成する

パスワード更新

現在のパスワードと新しいパスワードを入力して、パスワードを更新する

  1. 現在のパスワードが正しいか useKey を用いて検証する ( validate password )
  2. パスワードを変更する
  3. ユーザーの全てのセッションを無効にする

パスワードの変更時には、ユーザーのセッションを必ず全て無効にすること

Make sure to invalidate all sessions of the user on password or privilege level change. You can create a new session to prevent the current user from being logged out.

セキュリティに関しては自己責任で。
個人的にはluciaをもっと使っていきたいです。(7月にstableが出るみたい)

このライブラリを検証していて、sveltekitめっちゃ良い(使いやすい!)ってなった。

以上。

Discussion