Afs35mm
Afs35mm

Reputation: 649

NextJS - Sending cookies to API server from getInitialProps

I'm using NextJS as a client side repository to talk to my backend API server (laravel). Auth is done via JWT stored in the cookies. It all works seamlessly when I send an auth request to https://my-backend-server.com/api/login, as I respond with a cookie, and set to the my-backend-server.com domain. And even when I send requests from the browser.

Problems arise when I want to load the page, and sent the request from getInitialProps, as this is a serverside call. How am I able to access the cookies to my-backend-server.com, and put those in the header, so the server-side request from NextJS is properly authorized?

Most of the answers say something about req.cookies or req.headers.cookies, however this is empty as the request in getInitialProps is to http://my-local-clientside-site.com

Upvotes: 5

Views: 10283

Answers (2)

felixmosh
felixmosh

Reputation: 35503

As you explained correctly, Next's getInitialProps is called on client & on server.

If your Next app & Api services are served from the same domain, your Api service can put the cookie on the domain, and it will work on the client side (browser).

Whenever your Next app accessing the api from server-side, you need to attach the cookie by yourself.

getInitialProps method on the server side gets on the context (first param) the request (as req) from the browser, that means that this request has the cookie.

If you have a custom server, you probably need add to it a cookieParser,

// server.js

import cookieParser from 'cookie-parser';
import express from 'express';
import next from 'next';

const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
app.prepare().then(() => {
  const nextHandler = app.getRequestHandler();

  const server = express();

  server.use(cookieParser());
  // -----------^

  server.get('*', (req, res) => nextHandler(req, res));
});

This parser will parse the Cookie header and put it as an object on the req.

After that, your req.cookie should have the cookie value (make sure that you see that the browser sends it in the document request) you can access it in your getInitialProps,

//pages/index.js

const IndexPage = () => <div>BLA</div>

IndexPage.getInitialProps = (context) => {
  if(context.req) {
    // it runs on server side
    axios.defaults.headers.get.Cookie = context.req.headers.cookie;
  }
};

I've given you an example that sets up axios to put the cookie on all requests that will be made from the client.

Upvotes: 6

Tejas Patel
Tejas Patel

Reputation: 1447

Felixmosh' answer is half correct. rather than context.req.cookie it should be context.req.headers.cookie.

const IndexPage = () => <div>BLA</div>

IndexPage.getInitialProps = (context) => {
  if(context.req) {
    // it runs on server side
    axios.defaults.headers.get.Cookie = context.req.headers.cookie;
    //make api call with axios - it would have correct cookies to authenticate your api call
  }
};

Upvotes: -3

Related Questions