1

我有一个 Next.js 应用程序,索引页面仅包含验证码,并且在成功输入后重定向到 mydomain.com/form 上的表单,并且效果很好。但我也可以在浏览器中输入

mydomain.com/form

并在没有验证码的情况下使用它,这显然是我不想要的。

除了从验证码页面重定向之外,有没有办法限制所有条目?只找到了我不需要的登录等解决方案。

我正在使用 react-google-recaptcha 包

这是我的索引页

function Captcha() {
  const reRef = useRef<ReCAPTCHA>(null);
  const router = useRouter()
  return (
    <div className={styles.container}>
      <h1>Подтвердите, что вы не робот</h1>
      <ReCAPTCHA
        sitekey={`${process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY}`}
        size="normal"
        ref={reRef}
        onChange={() => router.push('/form')}
      />
    </div>
  );
}
4

2 回答 2

0

其逻辑与基于认证上下文授权受限页面的逻辑相同。

在这种情况下,创建一个上下文提供程序,其中包含是否已完成 reCaptcha 验证的状态。然后在表单组件中使用useContext根据 reCaptcha 上下文提供的状态进行渲染或重定向

于 2021-09-21T13:14:33.680 回答
0

使用本指南解决了它。

TL:DR 基本上我在成功验证码后将令牌添加到本地存储,令牌是访问表单页面所必需的。

创建了一个名为 withAuth 的 HOC

import { useRouter } from "next/router";
const withAuth = (WrappedComponent: any) => {
  return (props: JSX.IntrinsicAttributes) => {
    // checks whether we are on client / browser or server.
    if (typeof window !== "undefined") {
      const Router = useRouter();

      const accessToken = localStorage.getItem("accessToken");

      // If there is no access token we redirect to "/" page.
      if (!accessToken) {
        Router.replace("/");
        return null;
      }

      // If this is an accessToken we just render the component that was passed with all its props

      return <WrappedComponent {...props} />;
    }

    // If we are on server, return null
    return null;
  };
};



export default withAuth;

更改验证码页面以在每次加载时清理本地存储,并在成功输入后放入令牌。

    function Captcha() {
  const reRef = useRef<ReCAPTCHA>(null);
  const router = useRouter()
  if(process.browser){localStorage.clear()}
  
  return (
    <div className={styles.container}>
      <h1>Подтвердите, что вы не робот</h1>
      <ReCAPTCHA
        sitekey={`${process.env.NEXT_PUBLIC_RECAPTCHA_SITE_KEY}`}
        size="normal"
        ref={reRef}
        onChange={() => 
          {
            localStorage.setItem("accessToken" , "1"),
            router.push('/form')
          }
        }
      />
    </div>
  );
}

export default Captcha;

并将我的表单组件传递给 withAuth(从导出默认主页更改)

export default withAuth(Home);
于 2021-09-23T06:31:17.503 回答