Next13でLowレベルなログイン管理の実装
使用ライブラリ
- Nextjs 13.4.1
- iron-session ^6.3.1
アプリ構成
src
+ middleware.ts
| App
| login
+ Page.tsx
| secure
+ Page.tsx
| Api
| login
+ route.ts
| secure
+ route.ts
-
middleware.ts
に権限確認を行うレイヤを設けます。 -
/api/login
から認証を行います。 -
/login
からログインを行います。 -
/api/secure
は認証済みユーザーのみアクセス可能です。
iron-sessionを使いセッションにユーザー情報を管理を行います。
ソースコード
middleware.ts
とapi
直下のroute.ts
を中心に解説します。
-
middleware.ts
ここには権限確認を行うロジックを実装してます。const needLogInPrefixes = [ '/secure', '/api/secure/' ]
認証を行うURLパターンを記載します。
if (needLogInPrefixes.some((prefix) => pathname.startsWith(prefix))) { console.log("path", pathname) const session = await getIronSession(req, res, sessionOptions); const { user } = session; console.log("auth check in middle ", user) if (user === undefined) { return NextResponse.redirect(new URL('/login', req.url)) } }
認証を行うURLにリクエストがあった際に認証されていることを検証します。
ユーザー情報がなければ/loin
ページに遷移します。 -
api/login/route.ts
const session = await getIronSession(req, res, sessionOptions); console.log("before ", session, session.user === undefined) if (session.user === undefined) { console.log("set user") const user = { isLoggedIn: true, login: "sample user", avatarUrl: "avatar_url" } as User session.user = user await session.save() } console.log("after ", session) return res
一部抜粋しました。
ユーザー情報がなければ改めて作成してセッションに格納します。 -
api/secure/route.ts
export async function GET(request: Request) { return new Response('Hello, Next.js!') }
middleware.ts
で認可を行うのでこのAPI内には認可ロジックはございません。
単純にHello Nextjs
を返却しているように動作してます。
シナリオー
-
localhost:3000/login
にアクセス -
login
ボタンを押下し、ブラウザのURLからlocalhost:3000/secure
にアクセス -
get secure data
ボタンを押下し、正常にデータを取得していることを確認します。 -
logout
を押下しloing画面に戻ります。 - この状態で
localhost:3000/secure
にアクセスする場合、login
画面に戻ります。
制約
nextj13からになりますが、serverSideProps
が使えないため、middleware.ts
から認可ロジックを入れることになりました。また、SSRのページからブラウザのRequestを扱えうことはできないようです。
補足
認可ロジックを自由に組み込み、拡張ができるかと思います。
下記のリポジトリに今回使用したソースを格納しております。
画面遷移に問題があり完全なソースではありません。もし使う際には適度修正お願いします。
https://github.com/dlstjq7685/nextjs13-iron-session
補足2
より良いソリューションがございましたらコメントなどにご教示いただければいいかと思います!