NextAuthのmiddlewareでページごとの認証チェックを実装する
PitPaでエンジニアをしています、hideです。
現在T3 Stackでプロダクト開発を行っています。
T3 Stackでは認証ライブラリとしてNextAuth.jsが使われており、今回NextAuth.jsのmiddlewareを使ってページごと認証チェックをする方法について調べたので記しておきます。
使用したバージョン
- next: 13.0.2
- next-auth: 4.17.0
middlewareでの設定
(Nexts.jsにおける)middlewareとは、pageへのリクエストを受け取った時にコードを実行できる機能です。src/
直下にmiddleware.ts(js)
を作成することで使うことができます。
認証チェックを行うにはmiddleware.ts
でnext-auth
が用意しているmiddleware
をexportするようにします。
export { default } from "next-auth/middleware";
基本的な使い方としては上記設定だけでページへのリクエスト時に認証チェックを行い、認証に失敗すればサインイン画面にリダイレクトされます。
これだと全てのページに対して認証チェックが走ってしまいますが、さらにconfig
オブジェクトをexportすることで適用するページを設定することができます。
こちらはnext
の機能で、middleware.ts
で設定した処理を特定のパスで実行できるようになります。
export { default } from "next-auth/middleware";
export const config = {
matcher: [
"/",
"/((?!non-protected).*)"
],
};
上記の設定で、トップページ/
へのリクエスト時に認証チェックを行うのと、
正規表現も使えるため、/non-protected
以外の/
配下の全ページに対して認証チェックを行うことができるようになりました。
next-authのコードを追ってみる
認証失敗時のリダイレクト先は?
/api/auth/signin
にリダイレクトされます。
(/api/auth/
配下はnext-authがデフォルトで用意してくれている画面・apiです)
オプションは以下のように、middlewareをラップする書き方で実装した場合に設定することができます。
/api/auth/signin
を除外してないのにアクセスできるのはなぜ?
middlewareのconfigで上記でリダイレクト先のデフォルトは/api/auth/signin
と書きましたが、
middleware.ts
のconfigで除外の設定をしていないはずなのに/api/auth/signin
にはsigninしていなくてもアクセスできます。
それは、
でauthPath
が、認証チェックをせずにreturn
するパス、の対象となっているためです。
/_next
, /_favicon.ico
も認証チェックの対象から外れています。
おわり
認証が必要なページを明示的に書いていくと、新たなページを作る際に対応が漏れてしまい、見せてはいけないページが見えてしまう可能性があります。
middlewareを使うことによって、デフォルトですべてのpageを認証チェックでき、正規表現によって不要なページだけを明示的に書けるので、見せてはいけないページが見えてしまう事が発生しないのでいいなと思いました。
Discussion