如何用Next-Auth在Next.js中批量保护多路由免受未授权访问
批量保护Next.js pages目录下learning文件夹页面的几种方法
方法1:封装高阶组件(HOC)
把登录校验逻辑抽成可复用的高阶组件,每个learning页面只需用它包裹,无需重复编写getServerSideProps。
先新建withAuth.js文件:
import { unstable_getServerSession } from "next-auth/next"; import { authOptions } from "../api/auth/[...nextauth]"; // 替换为你的authOptions实际路径 export function withAuth(Component) { const AuthComponent = (props) => <Component {...props} />; AuthComponent.getServerSideProps = async (context) => { const session = await unstable_getServerSession(context.req, context.res, authOptions); if (!session) { return { redirect: { destination: "/", permanent: false, }, }; } // 兼容原页面自带的getServerSideProps,合并返回结果 if (Component.getServerSideProps) { const componentProps = await Component.getServerSideProps(context); return { ...componentProps }; } return { props: {} }; }; return AuthComponent; }
在learning文件夹的页面中使用:
import { withAuth } from "../../withAuth"; // 路径根据实际结构调整 function LearningPage() { return <div>学习页面内容</div>; } export default withAuth(LearningPage);
方法2:使用Next.js中间件(Middleware)
如果你的Next.js版本是12及以上,推荐用Middleware批量拦截请求,无需修改任何页面代码,是最简洁的批量保护方案。
在项目根目录创建middleware.js文件:
import { unstable_getServerSession } from "next-auth/next"; import { authOptions } from "./pages/api/auth/[...nextauth]"; // 替换为你的authOptions路径 import { NextResponse } from "next/server"; export async function middleware(req) { // 匹配learning文件夹下的所有子页面 if (req.nextUrl.pathname.startsWith("/learning")) { const session = await unstable_getServerSession(req, null, authOptions); if (!session) { // 未登录则重定向到首页 return NextResponse.redirect(new URL("/", req.url)); } } // 已登录或非learning路径,允许正常访问 return NextResponse.next(); } // 指定要匹配的路径规则 export const config = { matcher: "/learning/:path*", };
方法3:自定义_app.js的getInitialProps
如果项目使用不支持Middleware的旧版Next.js,可以在_app.js中统一处理登录校验,但需注意该逻辑会影响所有页面,要准确判断路径是否属于learning文件夹。
修改pages/_app.js:
import { unstable_getServerSession } from "next-auth/next"; import { authOptions } from "./api/auth/[...nextauth]"; // 替换为你的authOptions路径 import App from "next/app"; function MyApp({ Component, pageProps }) { return <Component {...pageProps} />; } MyApp.getInitialProps = async (appContext) => { const appProps = await App.getInitialProps(appContext); const { req, res } = appContext.ctx; // 仅对learning路径下的页面做校验 if (req.url.startsWith("/learning")) { const session = await unstable_getServerSession(req, res, authOptions); if (!session) { res.writeHead(302, { Location: "/" }); res.end(); return {}; } } return { ...appProps }; }; export default MyApp;
内容的提问来源于stack exchange,提问作者Bilal Mohammad
相关产品推荐
相关产品推荐

