Hero img
next-auth IDパスワード認証を試す

next-authでIDとパスワードを入力する認証システムを構築する

next-authを使ってIDとPWでユーザの認証をしてみます。next-auth側はこの方法は非推奨なようです。ID,PWだけでアクセス可が欲しい人もいるかもしれない。


目次

  • NextAuth.js
  • 目標
  • 環境node
  • 前提条件
  • NextAuth設定
  • NextAuthの準備
  • プロバイダーの追加
  • APIの作成
  • routeのファイルにコードを書く
  • optionsの中身について
  • ts.route全コード
  • クライアント側page.tsx
  • まとめ

NextAuth.js

NextAuth.jsがどのように動いて認証してくれるのかを確認するため、パスワード認証を実装し確認する。その時はベーシック認証を使えばいいが...

目標

NextAuthを使ってとりあえず動く事を確認する。

next-auth-comp-video

環境node

  • Windows 10
  • Nextjs14
  • Nextjs app router
  • node 18.17.1
  • next-auth4.24.5

前提条件

  • Nextjsのapp routerが使える状態
  • nodejsがインストールされている
  • npmが使える

NextAuth設定

NextAuthを使うために必ず必要な物

  • NextAuthのパッケージダウンロード
  • .envファイルにURLとSECRETの追加
  • apiの追加

NextAuthの準備

  1. 1.パッケージをダウンロードします。
npm install next-auth
  1. 2.環境ファイルを作成し、変数を二つ追加します。
.env
#シークレットキーはとりあえずなんでも可
#NEXTAUTH_SECRET= "aaaaaaaaaaaaaa"でもOK
NEXTAUTH_SECRET= "シークレットキー"
NEXTAUTH_URL = "http://localhost:3000/api/auth/"

環境ファイル

NextAuthを使うために環境ファイル(env)が必須になります。

プロバイダーの追加

Nextjsのtemplateファイルにセッションプロバイダーを追加します。

app/template.tsx
import { SessionProvider } from "next-auth/react"//<--これ
export default function Template({ children, session }: { children: React.ReactNode, session: any }) {
  return (
    <div>
      <SessionProvider session={session}> <--これ
        {children}
      </SessionProvider>
    </div>
  )
}

APIの作成

NextAuthを使うにはapiは動的ルーティングにする必要があります。 app routerの場合は次のようなファイル構造になります。

├api
│  └auth
│    └[...nextauth]  
│        └route.ts
│
page.js等...

routeのファイルにコードを書く

route.tsにnextauthでパスワード認証ができるコードを書いていきます。
route.tsの全コードは目次ts.route全コードから確認ください。

app/api/auth/[...nextauth]/route.ts
import NextAuth, { NextAuthOptions } from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials"
const options : NextAuthOptions = {
debug : true,
session: {strategy:"jwt"}//セッショントークンの有効期限を指定できる。
providers: [...],//ここに配列で書くことで認証の種類を増やせる。google,twitter,password,email等...
callbacks:{...},//クライアントに返す値。
}
const handler= NextAuth(options) //<--重要
export { handler as GET, handler as POST };

この設定で「api/auth/何か」にAPI等アクセスがあった場合NextAuthが認証処理をしてくれます。 optionsを指定しない時はデフォルトの挙動をするのですが, あまり知らない 長くなるので公式をご覧ください。

optionsの中身について

providers

このprovidersはどの認証方法を有効にするかを記入します。例として、google,ID PW認証,github認証等があります。
今回はIDとPWでの認証なので以下のコードcredentialsを使います。
実際にID,PWで認証をする場合はcredentialsを検証し、ログインをはじく場合はnullを返してください。

providersの中身
providers:[
  CredentialsProvider({//パスワード認証のプロバイダーです。
  //このようにすると以下の画像のように表示されます。
        name: "ちゃんねるめい",
        credentials: {
          username: { label: "ユーザ名", type: "text", placeholder: "プレスホルダー" },
          password: {  label: "パスワード", type: "password" }
        },
          async authorize(credentials, req) {//パスワードチェックをここでする。
          const user = { id: "1", name: "J Smith", }
          /*
          credentialsはトークンと入力されたID,PWが渡される。
          credentials={csrfToken: 'セッションとーくん',
          username: 'user-name',
          password: 'inputpassword'}
          */
         //そのためここでID,PWチェックをすることで間違っていた場合ログインをはじくことができる。
          if (user) {//入力されていればOKにしている。
            return user
          } else {//認証はじく場合はnullを返す。
            return null
          }
        }
  })
]
next-auth-login-page

callbacks

コールバックとは?
認証成功後クライアント側に返す値です。
ここに値を追加することでクライアント側に色々な情報を渡すことができます。

callbacks
    callbacks: {
      //jwtの後session()が処理される。
      jwt({ token, user }) {
        if (user) {
          token.role = "管理者";
          token.ex = "adminの管理者"
        }
        return token;
      },
      // jwt()の後処理される。
      session({ session, token }) {
        session.user.role = token.role;
        return session;
      },
    },

ブラウザーのデベロッパーツールで確認すると以下のように値が返ってくる。 next-auth-res-value

ts.route全コード

ts.route全コード
import NextAuth, { NextAuthOptions } from "next-auth";
import CredentialsProvider from "next-auth/providers/credentials"
const options : NextAuthOptions = {
    debug: true,
    session: { strategy: "jwt" },
    providers: [
      CredentialsProvider({
        name: "ちゃんねるめい",
        credentials: {
          username: { label: "ユーザ名", type: "text", placeholder: "プレスホルダー" },
          password: {  label: "パスワード", type: "password" }
        }
        async authorize(credentials, req) {
          const user = { id: "1", name: "J Smith", email: "[email protected]" }
          if (user) {
            return user
          } else {
            return null
          }
        }
      })
    ],
    callbacks: {
      jwt({ token, user }) {
        if (user) {
          token.role = "管理者";
        }
        return token;
      },
      session({ session, token }) {
        session.user.role = token.role;
        session.user.backendToken = token.backendToken;
        return session;
      },
    },
  };
const handler= NextAuth(options) 
export { handler as GET, handler as POST };

これでサーバー側のAPI設定が終了しました。

クライアント側page.tsx

次はクライアント側のコードを書いていきます。
approuterではuse clientとクライアント側であることを明記する必要があります。

'use client'
import { useSession, signIn, signOut } from "next-auth/react"

export default function Home(props: any) {
  const { data } = useSession();
if (data) {
  console.log(data);
  return (
    <>
    ログインしています。 <br />
      <button onClick={() => signOut()}>ログアウト</button>
    </>
  )
}

return (
  <>
    ログインしていません。 <br />
    <button onClick={() => signIn()}>ログイン</button>
  </>
)
}

まとめ

next-authを使ってログイン処理ができました。
個人的に詰まった部分は環境ファイルが必ず必要だという事、NEXTAUTH_RULのURLの値が間違っていたこと、動的ルーティングをするためのファイル構成です。
ログイン処理をID PWですることは非推奨となっているのでこのような使い方はあまり無いはず。

関連記事

コメント

コメントを書く

質問や、間違いがありましたら、お気軽にどうぞ

※お名前とコメントの内容を入力してください。
※全てこのブログ上に公表されます。
※許可なく管理者によって修正・削除する場合がございます。 詳しくはプライバシーポリシーを参照ください