10

I have two API routes which I want to set two cookies in /api/login.js and remove them in /api/logout.js.

so this is my login API:

import { serialize } from 'cookie';

export default async (req, res) => {
  res.setHeader('Set-Cookie', [
    serialize('mytoken1', 'mytoken1Value', {
      path: '/',
    }),
    serialize('mytoken2', 'mytoken2Value', {
      path: '/',
    }),
  ]);

  res.writeHead(302, { Location: '/' });
  res.end();
}

and this is my logout API:

export default async (req, res) => {
  res.removeHeader('Set-Cookie')

  res.writeHead(302, { Location: '/api/login' });
  res.end();
}

but the logout doesn't remove the cookies so I still can see them in _app.js ---console.log(req.headers.cookie)--- when I reload the page. Do you know how to remove a cookie in this situation?

jps
  • 20,041
  • 15
  • 75
  • 79
Afsanefda
  • 3,069
  • 6
  • 36
  • 76

3 Answers3

13

So, after challenging too much with every solution I ended up with this and it works fine:

(I had multiple cookies and I had to use nodejs methods cause I was coding in nextjs API routes without any middleware)

export default async (req, res) => {
  /* remove cookies from request header */
  res.setHeader('Set-Cookie', [
    serialize('mytoken1', '', {
      maxAge: -1,
      path: '/',
    }),
    serialize('mytoken2', '', {
      maxAge: -1,
      path: '/',
    }),
  ]);

  res.writeHead(302, { Location: '/api/login' });
  res.end();
}

The point was the maxAge which should be -1 to make it expire. I tried it with Date.now(). And when you have multiple cookies you have to end the response after manipulating both of them.

Afsanefda
  • 3,069
  • 6
  • 36
  • 76
11

You can do it this way:

res.setHeader('Set-Cookie', 'mytoken1=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT');
res.setHeader('Set-Cookie', 'mytoken2=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT');

Source

UPD

src/pages/api/auth/signout.ts

import { NextApiHandler } from 'next';
import { NotFoundError } from 'errors/not-found-error';
import { errorHandler } from 'middlewares/error-handler';

const routeHandler: NextApiHandler = (req, res) => {
  if (req.method === 'POST') {
    res.setHeader('Set-Cookie', 'jwt=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT');
    res.send({});
  } else {
    throw new NotFoundError();
  }
};

export default errorHandler(routeHandler);
Edshav
  • 378
  • 1
  • 8
  • Does not work this way! It says res.setHeader is not defined – Afsanefda Jun 14 '20 at 04:20
  • Here my code and it works: file:```src/pages/api/auth/signout.ts``` ```import { NextApiRequest, NextApiResponse, NextApiHandler } from 'next'; import { NotFoundError } from 'errors/not-found-error'; const routeHandler: NextApiHandler = (req: NextApiRequest, res: NextApiResponse) => { if (req.method === 'POST') { res.setHeader('Set-Cookie', 'jwt=deleted; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT'); res.send({}); } else { throw new NotFoundError(); } }; export default routeHandler;``` – Edshav Jun 14 '20 at 20:49
  • could you please edit your answer and add this code to it so that it could be more readable? Thanks – Afsanefda Jun 15 '20 at 05:28
  • I added this snippet to my answer – Edshav Jun 15 '20 at 09:58
6

inside next.js api route you can try :

export default async(req, res) => {
    res.setHeader(
        "Set-Cookie", [
        `access=deleted; Max-Age=0; path=/`,
        `refresh=deleted; Max-Age=0; path=/`]
        );

    return res.status(200).json({
        success: 'Successfully logged out'
    });
}

or by use cookie.serialize from cookie npm package you can try :

import cookie from 'cookie';
export default async(req, res) => {
    res.setHeader('Set-Cookie', [
        cookie.serialize(
            'access', '', {
                expires: new Date(0),
                path: '/'
            }
        ),
        cookie.serialize(
            'refresh', '', {
                expires: new Date(0),
                path: '/'
            }
        )
    ]);

   return res.status(200).json({
       success: 'Successfully logged out'
   });


}

and inside server side props page you can use

export async function getServerSideProps(context) {
    context.res.setHeader(
        "Set-Cookie", [
        `access=deleted; Max-Age=0; path=/`,
        `refresh=deleted; Max-Age=0; path=/`]
        );
    return { props: { } }
}

i hope this helpful for you .

K.A
  • 1,399
  • 12
  • 24