0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

バイブコーディング全盛期に人力でAuth.jsを使ってNext.jsに認証機能を追加してみる(入力フォームとバリデーションの実装)

0
Last updated at Posted at 2025-12-09

概要

AIでの開発が盛んな昨今ではあるが、一旦ちゃんと理解したいのでAuth.jsを使ってNext.jsのフレームワークで認証機能を人力実装してみる。
前回がインストール + 設定ファイルの用意だったので今回からメインの設定に入っていく。

前提

まずは基本となるメールアドレスとパスワードを使った認証を実装してみる。
下記のページの内容を実施してみる。

方法

  1. auth.tsを下記のように修正(credentialsのプロバイダーのimportと認証プロバイダーへの追加、これをすることでメアド + パスワードという古からのロングセラーな方法で認証が可能になる。)

    auth.ts
    // TODO: 本モジュールはsrc/lib/直下に移動予定
    
    import NextAuth from "next-auth"
    import { ZodError } from "zod"
    import Credentials from "next-auth/providers/credentials"
    import { signInSchema } from "./lib/zod"
    // Your own logic for dealing with plaintext password strings; be careful!
    import { saltAndHashPassword } from "@/utils/password"
    import { getUserFromDb } from "@/utils/db"
    
    export const { handlers, auth } = NextAuth({
      providers: [
        Credentials({
          // You can specify which fields should be submitted, by adding keys to the `credentials` object.
          // e.g. domain, username, password, 2FA token, etc.
          credentials: {
            email: {},
            password: {},
          },
          authorize: async (credentials) => {
            try {
              let user = null
            
              const { email, password } = await signInSchema.parseAsync(credentials)
            
              // logic to salt and hash password
              const pwHash = saltAndHashPassword(password)
            
              // logic to verify if the user exists
              user = await getUserFromDb(email, pwHash)
            
              if (!user) {
                throw new Error("Invalid credentials.")
              }
            
              // return JSON object with the user data
              return user
            } catch (error) {
              if (error instanceof ZodError) {
                // Return `null` to indicate that the credentials are invalid
                return null
              }
            }
          },
        }),
      ],
    })
    
  2. src/components/auth/直下にsign-in.tsxを定義して下記の内容を記載(サインイン用のフォームをコンポーネントとして追加)

    src/components/auth/sign-in.tsx
    import { signIn } from "../../../auth"
    
    export function SignIn() {
      return (
        <form
          action={async (formData) => {
            "use server"
            await signIn("credentials", formData)
          }}
        >
          <label>
            Email
            <input name="email" type="email" />
          </label>
          <label>
            Password
            <input name="password" type="password" />
          </label>
          <button>Sign In</button>
        </form>
      )
    }   
    
  3. 下記を実行してZodというスキーマライブラリを導入(バリデーションと型定義を一緒に面倒見てくれるもの)

    pnpm add zod
    
  4. プロジェクトルートにlibディレクトリを作成しその中にzod.tsを追加し下記のように記載(型定義とバリデーションルールの設定を実施)

    lib/zod.ts
    import { object, string } from "zod"
    
    export const signInSchema = object({
      email: string({ required_error: "Email is required" })
        .min(1, "Email is required")
        .email("Invalid email"),
      password: string({ required_error: "Password is required" })
        .min(1, "Password is required")
        .min(8, "Password must be more than 8 characters")
        .max(32, "Password must be less than 32 characters"),
    })
    
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?