随着 Next.js 12 的发布,现在有了对使用 Vercel Edge Functions 的中间件的 Beta 支持。
https://nextjs.org/blog/next-12#introducing-middleware
中间件使用严格的运行时,支持标准的 Web API,如 fetch。> 这在使用 next start 时开箱即用,也适用于使用 Edge Functions 的 Vercel 等 Edge 平台。
要在 Next.js 中使用中间件,您可以创建一个文件 pages/_middleware.js。在这个例子中,我们使用标准的 Web API 响应 (MDN):
// pages/_middleware.js
export function middleware(req, ev) {
return new Response('Hello, world!')
}
JWT 身份验证示例
在next.config.js
:
const withTM = require('@vercel/edge-functions-ui/transpile')()
module.exports = withTM()
在pages/_middleware.js
:
import { NextRequest, NextResponse } from 'next/server'
import { setUserCookie } from '@lib/auth'
export function middleware(req: NextRequest) {
// Add the user token to the response
return setUserCookie(req, NextResponse.next())
}
在pages/api/_middleware.js
:
import type { NextRequest } from 'next/server'
import { nanoid } from 'nanoid'
import { verifyAuth } from '@lib/auth'
import { jsonResponse } from '@lib/utils'
export async function middleware(req: NextRequest) {
const url = req.nextUrl
if (url.searchParams.has('edge')) {
const resOrPayload = await verifyAuth(req)
return resOrPayload instanceof Response
? resOrPayload
: jsonResponse(200, { nanoid: nanoid(), jwtID: resOrPayload.jti })
}
}
在pages/api/index.js
:
import type { NextApiRequest, NextApiResponse } from 'next'
import { verify, JwtPayload } from 'jsonwebtoken'
import { nanoid } from 'nanoid'
import { USER_TOKEN, JWT_SECRET_KEY } from '@lib/constants'
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
if (req.method !== 'GET') {
return res.status(405).json({
error: { message: 'Method not allowed' },
})
}
try {
const token = req.cookies[USER_TOKEN]
const payload = verify(token, JWT_SECRET_KEY) as JwtPayload
res.status(200).json({ nanoid: nanoid(), jwtID: payload.jti })
} catch (err) {
res.status(401).json({ error: { message: 'Your token has expired.' } })
}
}