【问题标题】:Using 'useEffect' inside my App function in my _app.js for my NextJS app在我的 _app.js 的 App 函数中为 NextJS 应用程序使用“useEffect”
【发布时间】:2021-09-13 09:14:08
【问题描述】:

我计划在每次页面更改时使用 useEffect 在客户端检查我的会话有效性。我想知道这是否可行,或者当我以这种方式实施时可能存在哪些缺点。

这就是它的样子。

export default function App({ Component, pageProps }) {
 
  useEffect(() => {
    //check API to validate session
  }, [Component]);

  return (
   <Component {...pageProps}/>
  );
}

【问题讨论】:

    标签: reactjs authentication next.js server-side-rendering use-effect


    【解决方案1】:

    是的,伙计,这是可能的,但是使用 NextJs 你会失去服务器端渲染功能,在这种情况下,我建议你做一些类似 Override the getServerSideProps 函数并将会话验证添加到其中,因为 nextJs 服务器端可以访问cookie 和会话。

    这是你可以做的一个例子:

    withSSRAuth.ts(文件)

    import { GetServerSideProps, GetServerSidePropsContext, GetServerSidePropsResult } from 'next';
    import {
      getSession,
    } from 'next-auth/client';
    import { destroyCookie, parseCookies } from 'nookies';
    import { AuthTokenError } from 'services/errors/AuthTokenError';
    
    export function withSSRAuth<P>(fn: GetServerSideProps<P>): GetServerSideProps {
      return async (ctx: GetServerSidePropsContext): Promise<GetServerSidePropsResult<P>> => {
        const session = await getSession(ctx);
        const cookies = parseCookies(ctx);
        const { 'uberPlantao.user': savedUser } = cookies;
    
        if (!session && !savedUser) {
          return {
            redirect: {
              destination: '/',
              permanent: false,
            },
          };
        }
        try {
          return await fn(ctx);
        } catch (err) {
          if (err instanceof AuthTokenError) {
            destroyCookie(ctx, 'uberPlantao.user');
            destroyCookie(ctx, 'uberPlantao.token');
            destroyCookie(ctx, 'uberPlantao.refreshToken');
    
            return {
              redirect: {
                destination: '/',
                permanent: false,
              },
            };
          }
          return err;
        }
      };
    }
    

    然后将其用作您的 getServerSideProps(当您想在某个页面中验证会话时)

    页面 index.tsx(需要会话验证)

    import Image from 'next/image';
    import { useRef, useCallback } from 'react';
    import { FiUser, FiLock } from 'react-icons/fi';
    
    import { useRouter } from 'next/router';
    
    import { Form } from '@unform/web';
    import { FormHandles } from '@unform/core';
    import { toast } from 'react-toastify';
    import * as Yup from 'yup';
    
    import getValidationErrors from 'utils/getValidationErrors';
    import { withSSRAuth } from 'utils/withSSRAuth';
    
    import { Button } from 'components/Atoms/Button';
    import { FbButton } from 'components/Atoms/FbButton';
    import { Input } from 'components/Atoms/Input';
    import { Seo } from 'components/Atoms/Seo';
    import { Separator } from 'components/Atoms/Separator';
    
    import {
      Container, LogoContainer, FormContainer, ButtonsContainer, Footer,
    } from 'styles/pages/index';
    import { useAuth } from 'hooks/auth';
    
    type DataFormInfo = {
      email: string;
      password: string;
    }
    
    const Home = (): JSX.Element => {
      const formRef = useRef<FormHandles>(null);
    
      const { push } = useRouter();
      const { signInWithFacebook, isLoading, defaultSignIn } = useAuth();
    
      const handleFbLogin = async (): Promise<void> => {
        signInWithFacebook();
      };
    
      const handleLogin = useCallback(
        async (data: DataFormInfo) => {
          console.log('login');
        },
        [defaultSignIn, push],
      );
    
      return (
        <Container>
          <Seo title="Home | Uber de plantões" metaDesc="Created by thl dev" />
          <LogoContainer>
          </LogoContainer>
          <FormContainer>
            <Form ref={formRef} onSubmit={handleLogin} autoComplete="off">
            </Form>
          </FormContainer>
          <Separator className="sep" type="horizontal" customWidth={40} />
          <Footer>
          </Footer>
        </Container>
      );
    };
    
    export default Home;
    
    export const getServerSideProps = withSSRAuth(async () => ({
      props: {},
    }));
    

    每次您使用 withSSRAuth 作为 getServerSideProps 的包装器时,它都会验证是否有一些用户进入 cookie(您也可以使用 session,但在我的情况下,我使用了 cookie)

    如果没有用户,它将重定向到您可以选择的某个网址。

    这种验证会话的方法不是最好的,但它可以防止您的页面在通过客户端检查是否有用户时闪烁

    【讨论】:

    • 谢谢你。
    猜你喜欢
    • 2019-07-20
    • 2022-10-02
    • 2021-11-03
    • 2021-03-12
    • 2020-09-07
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    • 2020-06-17
    相关资源
    最近更新 更多