96

I am using Cookies module for setting cookie. Here is following my code:

var options = {
    maxAge: ALMOST_ONE_HOUR_MS,
    domain: '.test.com',
    expires: new Date(Date.now() + ALMOST_ONE_HOUR_MS)
};
var value = userInfo.token;
cookies.set("testtoken", value, options);

But in documentation I haven't found how to destroy this cookie.

Any suggestion would be appreciated.

hong4rc
  • 3,999
  • 4
  • 21
  • 40
Manwal
  • 23,450
  • 12
  • 63
  • 93
  • 2
    There doesn't appear to be a method for it in the module you linked, but [setting the cookie to expire in the past](http://stackoverflow.com/questions/5285940/correct-way-to-delete-cookies-server-side) (`expires: new Date(0)`) should invalidate the cookie. – Jonathan Lonowski Jan 16 '15 at 07:24
  • Thanks @JonathanLonowski it helped. – Manwal Apr 07 '16 at 05:38

12 Answers12

201

For webapp you can just set cookie in response as :

res.cookie("key", value);

and to delete cookie : Ref: https://expressjs.com/en/api.html#res.clearCookie

res.clearCookie("key");

and don't forget to:

res.end()

to avoid the web request hanging.

Adarsh Madrecha
  • 6,364
  • 11
  • 69
  • 117
vashishatashu
  • 7,720
  • 7
  • 29
  • 34
  • This is better solution. But, Is it different way? by not using cookie. Its just a `key` named `cookie` to response. I need to get more secure method for authentication. – Manwal Jul 06 '16 at 16:39
  • 6
    This is authentic and well documented here: http://expressjs.com/en/api.html#res.clearCookie – Ahsan Aug 25 '16 at 07:46
  • 4
    This isn't sending anything back to the client, and as a result the client isn't deleting their cookie. – Michael Mar 25 '17 at 00:27
  • 1
    @Michael This just sets a header. You still have to send the response with `res.end()` or similar. Then the response is sent and the cookie is cleared. – Aurast Dec 10 '20 at 01:25
  • For those of you using Express and/or Nest for REST APIs, make sure you are receiving a response object in your logout route, call `request.session.destroy(() => {...})` and in that callback function passed in, call the `clearCookie()` method above, then make sure to call `response.end()` to avoid the web request hanging or timing out. – OzzyTheGiant Apr 06 '21 at 02:10
65

There is no way to delete a cookie according to the HTTP specification. To effectively "delete" a cookie, you set the expiration date to some date in the past. Essentially, this would result in the following for you (according to the cookies module documentation):

cookies.set('testtoken', {maxAge: 0});

Or according to the HTTP specification:

cookies.set('testtoken', {expires: Date.now()});

Both of which should work. You can replace Date.now() with new Date(0) for a really old date.

Bruno
  • 401
  • 5
  • 13
Deathspike
  • 8,582
  • 6
  • 44
  • 82
  • There are certain cases when cookie needs to be destroyed based on user and application level triggers where we need to destroy cookie. – vashishatashu Jul 08 '16 at 06:56
  • 4
    @vashishatashu I'm not sure what it is you are trying to say. There is no difference between "destroying" a cookie or setting its expire date to a date that has already passed. That is the exact same thing. Read the HTTP specification for details on cookie mechanisms, or use your favorite language to "destroy" a cookie and look at the headers in your development tools (note the Set-Cookie). – Deathspike Jul 10 '16 at 22:02
  • 3
    Shouldn't this be `maxAge: 0` ? "a number representing the milliseconds from Date.now() for expiry" https://github.com/pillarjs/cookies – mh8020 Jul 10 '19 at 09:29
  • 2
    Be careful with `new Date(0)`. Certain implementations might treat it as a special case and behave unpredictably. I just confirmed that using Date(0) with `simple-cookie` stringify() creates a session cookie instead of deleting it. In this case `Date.now()` or `new Date()` work fine, as well as `new Date(1)` but not 0. – ArticIceJuice Aug 30 '19 at 17:00
37

While one other answer is correct, deleting a cookie from an express.js webapp is done by invocing the following method:

res.clearCookie("key");

But there's a caveat!

Your cookie options (except expires) need to be the same as when you set it. Otherwise browsers will NOT remove the cookie. So use the same domain, security setting etc. (reference: https://expressjs.com/en/4x/api.html#res.clearCookie)

Jesper Bylund
  • 883
  • 9
  • 23
  • 1
    I'm afraid I don't understand your sentence? Removing a cookie does not update the options? But the options need to be the same as the set cookie, otherwise the cookie will not be removed. – Jesper Bylund Nov 25 '17 at 10:52
  • 1
    @Manwal it doesn't matter. The point is you must INCLUDE the same options. If you "miss" one option, the cookie is not removed. – Jesper Bylund Nov 25 '17 at 11:05
  • This is not correct. You don't need to pass any options when using clearCookie. – Incinerator Nov 27 '17 at 09:04
  • 1
    @Incinerator It's in the official documentation, and kept me debugging quite a while: https://expressjs.com/en/4x/api.html#res.clearCookie – Jesper Bylund Nov 28 '17 at 09:57
  • 1
    I stand corrected, although in my case I was able to clear the cookie even without passing any options. (PS: I'll remove my downvote but I cannot do so unless you edit your answer) – Incinerator Nov 28 '17 at 12:59
  • 1
    @Incinerator Not all browsers. :) Edited! – Jesper Bylund Nov 28 '17 at 14:38
  • Is there a way to dynamically get the same cookie options from when the cookie was set? In my case, Set-Cookie automatically set the Path to a subfolder (which changes depending on the environment), but clearCookie is trying to clear on the / path by default. – Connor Mar 05 '20 at 21:18
  • 1
    @Connor, its easier to set the cookie to a expired date. but if you want to use this solution, answering your question, you can export the cookie options you defined when you created the cookie into a separate file, then call that "object" in the both places, when creating the cookie, and when destroying it – Normal May 08 '22 at 22:38
12

I was going through the same problem a few days ago. After discussing it with a friend, I think this is the best solution.

res.setHeader('set-cookie', 'mycookie=; max-age=0');

Advantages:

  • only use node
  • simple to understand

credits: @andy

Mark Colling
  • 173
  • 1
  • 9
  • also, one advantage, all programmers will understand this, as it's how everyone out there is doing it. not only in nodejs – Normal May 08 '22 at 22:39
11

I'm using this with cookie-parser module:

router.get('/logout', function(req, res){
    cookie = req.cookies;
    for (var prop in cookie) {
        if (!cookie.hasOwnProperty(prop)) {
            continue;
        }    
        res.cookie(prop, '', {expires: new Date(0)});
    }
    res.redirect('/');
});
Sandro Wiggers
  • 4,440
  • 3
  • 20
  • 25
  • 1
    Hey, why are you checking for `if (!cookie.hasOwnProperty(prop)) { continue; }` ? Wouldn't that cookie be coming from the hash itself? So why check it when the hash gives you the key and then you delete the key – Sana May 21 '18 at 22:08
  • 1
    For me the `expires` option was throwing an error so I added the `maxAge` to 0 – Harry Theo Sep 12 '19 at 15:23
9

To delete any http cookie if we just try to clear it from response [using res.clearCookie("key")], it is definitely not going to work. In reality, to delete http cookie, domain and path are very important.

Domain and path define the scope of the cookie. In face, they essentially tell the browser what website the cookie belongs to. Sending the same cookie value with ; expires appended is also a bad idea since you want the content to be destroyed, but that is not going to happen.

The best idea would be invalidating the cookie by setting the value to empty and include an expires field as well like below:

res.cookie("key","empty the key content", {expires:old date, domain:'.example.com', path:'/'});

res.cookie("token", "", { expires: new Date(0),domain:'.test.com', path: '/' });

Hope this helps!!!

Sunil Garg
  • 14,608
  • 25
  • 132
  • 189
Kavitha Vikas
  • 257
  • 4
  • 4
6

I am using cookie-parser as well, and upper answers lead me to the solution. In my case I needed to add overwrite: true as well, otherwise new cookie key was added.

So my final solution looks like:

res.cookie('cookieName', '', {
      domain: 'https://my.domain.com',
      maxAge: 0,
      overwrite: true,
    });
Gašper Gračner
  • 129
  • 1
  • 12
3

When using in production with SSL, you need to specify the domain. This domain must correspond to the one, which is used to store the cookie!

For example:

res.clearCookie('sid', {domain: ".somedomain"})
Sanzhar Dan
  • 351
  • 4
  • 11
1

create cookie with expires time

res.cookie("keyname", data, {
    expires: new Date(Date.now() + 1000 * 60 * 15),  
})

Remove cookie

res.clearCookie("key name here");
Md Mahir
  • 81
  • 5
0

I have tried all the solutions, and none worked until I found this one.

  1. I set up my cookie like this:
res.writeHead(200, {
   "Set-Cookie": `token=${accessToken}; HttpOnly; path=/`,
   "Access-Control-Allow-Credentials": "true",
});

res.end();
  1. Then destroyed it like this:
res.writeHead(200, {
    "Set-Cookie": `token=; HttpOnly; path=/; max-age=0`,
});
res.end();
M. Dudek
  • 978
  • 7
  • 28
0

Another way to destroying cookies from the server. Just set negative integer as a maxAge. One more thing that keep in mind, don't forget to set a path when will set or destroy cookie.

Muhammad Minhaj
  • 109
  • 1
  • 7
-1

The Best way to doing this

before you set the like token you should remove that first like that

res.clearCookie('token');
res.cookie('token',token, { maxAge: 900000, httpOnly: true });
aadilraza339
  • 103
  • 3
  • you either do the first, or the second one. also the first one, folks are saying you must specify the options argument in order to correctly clear the cookie – Normal May 08 '22 at 22:41