Home > Blockchain >  Return additional data in higher-order authentication component in Next.js
Return additional data in higher-order authentication component in Next.js

Time:04-28

I have the following piece of code:

export const requireAuth = (gssp: GetServerSideProps) => {
  return async (ctx: GetServerSidePropsContext) => {
    const { req } = ctx;
    let session = null;

    if (req?.headers?.cookie) {
      session = await getSession(req?.headers?.cookie);
    };

    if (!session) {
      return {
        redirect: {
          permanent: false,
          destination: '/login',
        },
      };
    };
    return await gssp(ctx);
  };
};

I am trying to also return the session in await gssp(ctx), I'm fairly new to NextJS and I can not manage to find any related info on this.

The current method allows me to use this component in the following way:

export const getServerSideProps: GetServerSideProps = requireAuth(async _ctx => {
  let account;
  let stats = {};

  if (_ctx?.req?.headers?.cookie) {
    account = await getSession(_ctx?.req?.headers?.cookie);
  }

  try {
    const X = fetchSomeData...;
  } catch (error) {
    console.log('Pages/Index Fetching Error: ', error);
  }

  return {
    props: {
      account: account,
      data: X,
      navbar: true,
      footer: true,
    },
  };
});

Which permits additional logic on the page where it is used, compared to other HOR methods.

Any way I could return the session in the main requireAuth component instead of fetching it on each page?

CodePudding user response:

You have control over what the higher-order function passes to the actual gssp function, so you can simply pass the session in the ctx object.

export const requireAuth = (gssp: GetServerSidePropsWithSession) => {
    return async (ctx: GetServerSidePropsContext) => {
        const { req } = ctx;
        const session = req?.headers?.cookie ? await getSession(req?.headers?.cookie) : null;

        if (!session) {
            return {
                redirect: { permanent: false, destination: '/login' }
            };
        };

        const ctxWithSession = { ...ctx, session };

        return await gssp(ctxWithSession);
    };
};

You can then access the session inside your getServerSideProps code.

interface GetServerSidePropsContextWithSession extends GetServerSidePropsContext {
    session?: Session;
}

type GetServerSidePropsWithSession<P extends { [key: string]: any } = { [key: string]: any }> = (
    context: GetServerSidePropsContextWithContext
) => Promise<GetServerSidePropsResult<P>>;

export const getServerSideProps: GetServerSidePropsWithSession = requireAuth(async _ctx => {
    const account = _ctx.session;
        
    // Remaining code...
});

Note that you'll need to extend the GetServerSideProps type to expect the session field.

  • Related