Guide/guides
認証アプリを作る
このガイドでは、ユーザー登録・ログイン・保護されたルートを備えたアプリケーションを構築します。空のディレクトリから認証フロー完成まで、10分以内で完了できます。
認証アプリを作る
このガイドでは、ユーザー登録・ログイン・保護されたルートを備えたアプリケーションを構築します。空のディレクトリから認証フロー完成まで、10分以内で完了できます。
Note
これはタスク指向のガイドです。セッション、ガード、ユーザープロバイダーの詳細は認証ガイドを参照してください。
前提条件
- Bun 1.1 以降
- Docker Desktop (Compose v2) — Postgres 用
1. プロジェクトを作成する
bunx create-guren-app my-auth-app --mode ssr
cd my-auth-app
bun install
2. 認証機能を追加する
add auth ジェネレーターを使うと、コントローラー、Inertia ページ、ユーザーモデル、マイグレーション、セッションミドルウェアが一括で生成されます:
bunx guren add auth
生成されるもの:
app/Http/Controllers/Auth/LoginController.tsとRegisterController.ts- パスワードとリメンバートークンのカラムを持つ
app/Models/User.ts resources/js/pages/Auth/配下の Inertia ページ- アプリケーションプロバイダーに登録済みの
AuthProvider - 開発環境向けのデフォルト設定が適用されたセッションミドルウェア
routes/web.tsに接続された認証ルート
3. データベースを起動する
docker compose up -d
マイグレーションを実行して users テーブルを作成します:
bunx guren db:migrate
4. 型マニフェストを生成する
bun run codegen
ルートとページの型付きマニフェストが生成され、コントローラーとフロントエンドコンポーネントの型安全性が確保されます。
5. 開発サーバーを起動する
bun run dev
http://localhost:3333/register でアカウントを作成し、http://localhost:3333/login でログインできます。
6. 主要なコードを理解する
LoginController
生成されるコントローラーは Zod でバリデーションを行い、認証ガードに処理を委譲します:
import { Controller } from '@guren/core'
import { z } from 'zod'
import { pages } from '@/.guren/pages.gen'
const LoginSchema = z.object({
email: z.email(),
password: z.string().min(1),
remember: z.boolean().optional(),
})
export class LoginController extends Controller {
async show() {
return this.inertia(pages.auth.Login)
}
async login() {
const { email, password, remember } = await this.validateBody(LoginSchema)
const ok = await this.auth.attempt({ email, password }, remember)
if (!ok) {
return this.back().withErrors({ email: '認証情報が正しくありません。' })
}
return this.redirect('/dashboard')
}
async logout() {
await this.auth.logout()
return this.redirect('/login')
}
}
認証ミドルウェア
ジェネレーターが登録する auth エイリアスを使って、ルートグループを保護します:
import { Router } from '@guren/core'
export function registerWebRoutes(router: Router): void {
// 公開ルート
router.get('/login', [LoginController, 'show']).name('login.show')
router.post('/login', [LoginController, 'login']).name('login')
router.post('/logout', [LoginController, 'logout']).name('logout')
// 保護されたルート
router.middleware('auth').group((auth) => {
auth.get('/dashboard', [DashboardController, 'index']).name('dashboard')
})
}
保護されたページ
保護されたコントローラー内では this.auth で現在のユーザーにアクセスできます:
export class DashboardController extends Controller {
async index() {
const user = await this.auth.userOrFail()
return this.inertia(pages.dashboard.Index, { user })
}
}
7. フローを検証する
/registerにアクセスしてユーザーを作成する/loginにアクセスして作成した認証情報でログインする/dashboardに遷移し、ユーザー名が表示されることを確認する- シークレットウィンドウで
/dashboardにアクセスし、/loginにリダイレクトされることを確認する - ログアウトして、ログインページに戻ることを確認する