I’ve been developing applications for a long time. Using cookies was a concept I was vaguely aware of, but I never really focused on in the past. I ran into a dilemma that I just couldn’t get around. I’m working on site / responsive app protected via JSON (JavaScript Object Notation) Web Tokens for authentication and user identification. The site I’m working on is a single page web app in which the content is populated after authentication via AJAX calls. The site uses NodeJS, Express Generator and jQuery Mobile.

I want to add a route to the site that generates a server generated PDF report. To keep things simple, I wanted to do a GET request via link to a new tab. The trouble was figuring out a way to protect that page, without additional login and authentication. It turns out sending content via Cookies works pretty well.

Library used: cookie-parser. Whoa.. I never realized that library is included in Express Generator. Nothing extra to load, its already there. In my case, I set a cookie at the server in a response header after the initial authentication process. Did a bit of testing, and this is totally easy. The cookie is included in any subsequent server request including a simple < a href="./report" target="_blank">Create a PDF report... Obviously the target=”_blank” opens the link in a new tab. I did a whole lot of testing, and there just was no way to open a redirect to a new tab using a post request to generate a pdf file.

The other thing I wanted to understand was the use of the use of Cookies and signing. I did a bunch of testing, and here’s what I found:

  • In app.js, I set app.use(cookieParser('MY SECRET CODE'));
  • In my routes file, I set response.cookie("cookie_name" , 'this is my first cookie', {signed: true});
  • Open up my app in the browser, perform authentication, check cookies value using Chrome browser and Inspect dev tools.
  • There are two ways to do this: using Inspect –> Appplication Tab –> Cookies or in the browser console type document.cookie.
  • "cookie_name=s%3Athis%20is%20my%20first%20cookie.3Q8973HkDKE4vElmeYBGp%2FRnPAKnuePvhZoLSG8Gjpc"
  • Test a submit via link to new tab. Review data on the server. Sure enough, in the submitted request, I find a value “cookies”, but also a value for “signedCookies”.req.signedCookies {cookie_name: "this is my first cookie"}
  • But hang on a second. That cookie in the browser looks like something easy to fake out. Let’s try this and see what happens. I go back to the site in the browser. Clear out the cookies. Create a new fake cookie, a=b, using the generated hash observed above… document.cookie = "a=b.3Q8973HkDKE4vElmeYBGp%2FRnPAKnuePvhZoLSG8Gjpc"
  • Test link submit again. Carefully read the contents of the request object. cookies object shows a=b… BUT request.signedCookies is totally blank {}

And that means I can trust the system to identify somebody playing games with cookies, as long as I use request.signedCookies for my authentication work. This is pretty awesome.

And yes I did go back and create response.cookie("a" , 'b', {signed: true}); and the hash code is something totally different from previous.

I will say until I went through this testing I was not really aware of how easy this stuff really is. Note, I do have to commend the folks at Microsoft for the VS Code developer tool. That makes it so easy to step through server code and really understand request and response objects. Many thanks to all the folks supporting that tool.