💁‍♂️

Next-authでカスタムログインページを作成

2023/05/04に公開

そもそも

Next-authのデフォルトのログインページってまじでいけてない
デフォルトのページは簡略化されていてシンプルでわかりやすいのですが、作成しているアプリケーションとはイメージが合わないこととかありますよね??ありますね?

自分も、まあ、機能的に動いてるしこれでいっか。などと思っていましたが、とうとう重い腰を上げて修正することを決意したのです。

さあ、あなたも一緒にNextauthをオシャレにう買う旅に出ませんか!!??

じゃあどうやるのよ

TL;DR

NextAuthのauthOption(これは書き方がそれぞれあるが、公式がこの書き方なので準拠)にpagesを追加する。

pages/api/auth/[...nextauth].ts
export const authOptions: AuthOptions = {
  // Configure one or more authentication providers
  providers: [
    CredentialsProvider({
      name: 'Credentials',
      credentials: {
        mail: { label: 'mail', type: 'text', placeholder: 'メールアドレス' },
        password: { label: 'password', type: 'password' },
      },
      async authorize(credentials, req): Promise<any> {
        // ... ログイン処理を記載
    }),
    GithubProvider({
      clientId: process.env.GITHUB_ID || '',
      clientSecret: process.env.GITHUB_SECRET || '',
    }),
  ],
+  pages: {
+    signIn: '/auth/signin',
+  },
  secret: process.env.NEXT_PUBLIC_SECRET,
  callbacks: {
    ...
  },
}

export default NextAuth(authOptions)

こんな感じでpagesを追加します。

そのページ内にログイン用のコンポーネントを使用していきます。

pages/auth/signin.ts

import { useState } from 'react';
import { useRouter } from 'next/router';
import { useForm } from 'react-hook-form';
import axios from 'axios';

const LoginPage = async (event: React.FormEvent<HTMLFormElement>) => {
  event.preventDefault()
    const data = new FormData(event.currentTarget)
    const mail = data.get('email')
    const password = data.get('password')

  const onSubmit = async (data) => {
    try {
      await signIn("credentials", {
        redirect: false,
        mail,
        password,
      }).then(res => {
        if (res?.error) {
          console.log(res.error)
        } else {
          router.push('/')
        }
      })
    } catch (err) {
      console.log(err)
    }
  };

  return (
    <div>
      <h1>ログインページ</h1>
      <form onSubmit={handleSubmit(onSubmit)}>
        <div>
          <label htmlFor="email">メールアドレス</label>
          <input type="email" id="email" {...register('email', { required: true })} />
          {errors.email && <p>メールアドレスを入力してください</p>}
        </div>
        <div>
          <label htmlFor="password">パスワード</label>
          <input type="password" id="password" {...register('password', { required: true })} />
          {errors.password && <p>パスワードを入力してください</p>}
        </div>
        {errorMessage && <p>{errorMessage}</p>}
        <button type="submit">ログイン</button>
      </form>
    </div>
  );
};

export default LoginPage;

ここで注目していただきたいのは、await signIn()のところです。
引数にcredentialsをとることができ、そこにemailとかpasswordを埋め込んでいきます。

そうすると、デフォルトのページでログインを行なっていた時のように処理を遂行することができます。

まあ、後の処理はまた今度でも記事にしてみようかと思います〜〜〜。

お疲れ様でした😊

参考文献

https://next-auth.js.org/configuration/pages

筆者

https://twitter.com/ryuji_vlog

Discussion