Search code examples
node.jsreactjsjwtnext.jsnestjs

Why are cookies not sent to the server via getServerSideProps in Next.js?


Cookies are not sent to the server via getServerSideProps, here is the code in the front-end:

export async function getServerSideProps() {
  const res = await axios.get("http://localhost:5000/api/auth", {withCredentials: true});
  const data = await res.data;
  return { props: { data } }
}

On the server I have a strategy that checks the access JWT token.

export class JwtStrategy extends PassportStrategy(Strategy, "jwt") {
    constructor() {
        super({
            ignoreExpiration: false,
            secretOrKey: "secret",
            jwtFromRequest: ExtractJwt.fromExtractors([
                (request: Request) => {
                    console.log(request.cookies) // [Object: null prototype] {}
                    let data = request.cookies['access'];
                    return data;
                }
            ]),
        });
    }

    async validate(payload: any){
        return payload;
    }
}

That is, when I send a request via getServerSideProps cookies do not come to the server, although if I send, for example via useEffect, then cookies come normally.


Solution

  • That's because the request inside getServerSideProps doesn't run in the browser - where cookies are automatically sent on every request - but actually gets executed on the server, in a Node.js environment.

    This means you need to explicitly pass the cookies to the axios request to send them through.

    export async function getServerSideProps({ req }) {
        const res = await axios.get("http://localhost:5000/api/auth", {
            withCredentials: true,
            headers: {
                Cookie: req.headers.cookie
            }
        });
        const data = await res.data;
        return { props: { data } }
    }
    

    The same principle applies to requests made from API routes to external APIs, cookies need to be explicitly passed as well.

    export default function handler(req, res) {
        const res = await axios.get("http://localhost:5000/api/auth", {
            withCredentials: true,
            headers: {
                Cookie: req.headers.cookie
            }
        });
        const data = await res.data;
        res.status(200).json(data)
    }