防止直接访问 Next.js 中的页面,同时允许从应用程序内部访问

问题描述 投票:0回答:1

我正在开发 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: {},
  };
};
reactjs next.js middleware
1个回答
0
投票

这似乎是身份验证保护问题。在根文件夹中添加 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

最新问题
© www.soinside.com 2019 - 2024. All rights reserved.