我正在开发 Next.js 应用程序,我有一个特定的页面,我们称之为“谢谢”,我想阻止用户直接通过 URL 访问该页面。但是,我希望仅允许通过应用程序内的内部导航(例如单击按钮)访问此页面。
我尝试使用中间件功能将直接请求重定向到主页,并且它按预期工作。但是,当我尝试使用客户端路由(例如 router.push("/thank-you"))导航到“谢谢”页面时,它仍然会触发中间件并重定向到主页。
这是代码的简化版本:
中间件函数(middleware.ts):
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function middleware(request: NextRequest) {
return NextResponse.redirect(new URL("/", request.url));
}
export const config = {
matcher: ["/thank-you"],
};
按钮单击处理 (YourComponent.tsx):
import { useRouter } from "next/router";
export default function Home() {
const router = useRouter();
const handleButtonClick = () => {
router.push("/thank-you");
};
...
}
如何防止直接访问“谢谢”页面,同时允许通过应用程序内的内部导航进行访问?
任何帮助或建议将不胜感激!
更新
我尝试了
getServerSideProps
,但仍然有同样的问题。
单击按钮也会重定向到主页。
export const getServerSideProps = () => {
return {
redirect: {
permanent: false,
destination: "/",
},
props: {},
};
};
这似乎是身份验证保护问题。在根文件夹中添加 AuthGuard。如果使用应用程序 Router,它将进行布局,并使用 redux 或其他状态管理来控制访问。
根布局
export default function RootLayout({
children,
}: IPageParamsLayout) {
return (
<html>
<body>
<main>
<AuthGuard>{children}</AuthGuard>
</main>
</body>
</html>
);
}
AuthGuard
"use client"
import { useRouter } from "next/navigation";
import { usePathname } from "next/navigation";
// Authguard would have all redirection logic to keep redirection in one place and prevent redirection loop.
const AuthGuard = (children) => {
const pathname = usePathname();
const router = useRouter();
const dispatch = useAppDispatch();
const authRights = useAppSelector(authRights);
if(pathname === 'thank-you' && !authRights.thankYou) {
router.push(`/`);
}
return (
<>{children}</>
)
}
export default AuthGuard
重定向到谢谢的组件。
"use client"
const BeforeThankYou = () => {
const dispatch = useAppDispatch();
return (
<div onClick={() => {
dispatch(setAuthRights({
thankYou: true
}))
router.push("/thank-you")
}}>Click to Thank You Page</div>
)
}
export default BeforeThankYou