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.tsconst 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.tsexport 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
より良いソリューションがございましたらコメントなどにご教示いただければいいかと思います!