Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass context back to GetServerProps handler #48

Open
al-bimani opened this issue Jul 4, 2022 · 4 comments
Open

Pass context back to GetServerProps handler #48

al-bimani opened this issue Jul 4, 2022 · 4 comments

Comments

@al-bimani
Copy link

al-bimani commented Jul 4, 2022

Hello, i'm trying to get the query from the context argument of getServerSideProps. But i can't achieve this if i follow the example you provided.

export const getServerSideProps = setup(handler)

For setup function is passing req and res to handler and not the full context object which includes query property as well.

 const req = isApi
    ? (args[0] as NextApiRequest) // (*req*, res)
    : (args[0] as GetServerSidePropsContext).req; // (context).req
  const res = isApi
    ? (args[1] as NextApiResponse) // (req, *res*)
    : (args[0] as GetServerSidePropsContext).res; // (context).res
    
    // ...
    
    return handler(req as NextApiRequest, res as NextApiResponse);

that function seems to be implemented to work on pages/ on getServerSideProps so is there any point from typing the handler to be NextApiHandler instead of GetServerSideProps? and how can i get the query property?
Thanks.

@virendra-koloapp
Copy link

same issue

@virendra-koloapp
Copy link

type TSetupCSRF = (serverSideProps: GetServerSideProps) => GetServerSideProps;

const setupCSRF = setup as unknown as TSetupCSRF;

doing this in TS but setup is not passing context object , it is passing req and res object.

@virendrapatel62
Copy link

Hello,

I have created my own middleware and injector for getServerSideProps and is working fine.

npm install csrf


import Cookies from "cookies";
import Tokens from "csrf";
import {
  GetServerSideProps,
  NextApiHandler,
  NextApiRequest,
  NextApiResponse,
} from "next";

type TSetupCSRF = (serverSideProps: GetServerSideProps) => GetServerSideProps;

const {
  CSRF_SECRET = (() => {
    throw new Error("CSRF_SECRET Required.");
  })(),
} = process.env;

const IgnoreCSRFMethods: string[] = [];

const tokens = new Tokens();

const csrfValidator = (handler: NextApiHandler) => {
  return (request: NextApiRequest, response: NextApiResponse) => {
    const method = request.method as string;

    if (IgnoreCSRFMethods.includes(method)) {
      return handler(request, response);
    }

    const { "CSRF-TOKEN": token } = request.cookies || {};

    const sendError = () => {
      return response.status(403).json({ error: "CSRF token missing" });
    };

    console.log(token);

    if (!token) {
      return sendError();
    }

    const isValid = tokens.verify(CSRF_SECRET, token);

    if (!isValid) {
      return sendError();
    }

    return handler(request, response);
  };
};

const csrfInjector: TSetupCSRF = (getSSP) => {
  return async (context) => {
    const cookies = new Cookies(context.req, context.res);
    const token = tokens.create(CSRF_SECRET);
    cookies.set("CSRF-TOKEN", token);
    return getSSP(context);
  };
};

export { csrfInjector, csrfValidator };


now wrap injector in getServerSideProps and validator on api handler.

export const getServerSideProps: GetServerSideProps = csrfInjector(
  async ({ query }) => {
   
    return {
      props: {
        
      },
    };
  }
);



const handler: NextApiHandler = (request, response) => {
  response.json({
    now: Date.now(),
  });
};

export default csrfValidator(handler);


@DerekWolfie
Copy link

It works @virendrapatel62 the secret has only one layer so it's not really that safe

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants