This content originally appeared on Alligator.io and was authored by Alligator.io
Cookie management is not the most difficult thing to do in Express.js, but there are a lot of solutions out there to help you which can make things quite confusing. We’re going to look at a very raw implementation of cookies. If you want to learn more about what browser cookies are, I recommend reading this article first.
What We’re Building
We’re going to make a little grocery store application using Express.js and as little other libraries as possible. You can see my extremely boring implementation of it at temporas.laeeto.com To get started we will run:
$ npm init
$ npm install express body-parser cors
Our application will have an app.js
file and a productDao.js
file.
Module: app.js
const express = require('express');
const bodyParser = require('body-parser');
const cors = require('cors');
const productDao = require('./productDao.js');
// We will define this later
const sessionHandler = require('./sessionHandler');
const apiRouter = require('./apiRouter');
const app = express()
// Our API will be listening on port 4000
app.set('port', process.env.PORT || 4000)
// We support json requests
app.use(bodyParser.json())
// Allow cors everywhere
app.use(cors())
// This will manage our sessions
app.use(sessionHandler)
// Our app had one route to get the products in our database
app.use('/api', apiRouter)
// Launching our server on our app's port
const server = app.listen(app.get('port'), () => {
console.log(`Shopping App is running on port ${app.get('port')}`)
})
export default server
Module: apiRouter.js
const router = require('express')
// Our app had one route to get the products in our database
app.get('/product/all', (req, res) => {
// This array simulates our database
const allProducts = [
{name: 'blue cheese', type:'cheese'},
{name: 'brocolli', type: 'vegetable'},
{name: 'cookie', type: 'snack'}
];
res.status(200).send(allOurProducts)
})
// add item to the cart
app.post('/cart', (req,res)=> {
// We'll write this code later
})
// get all items in the shopping cart
app.post('/cart', (req,res)=> {
// We'll write this code later
})
// Allows our user to checkout
app.post('/checkout', (req, res) => {
// We'll write this code later
})
Sending Cookies in Express.js
Before looking at any other library, we can see that Express has a cookie
property on the Response
object.
Module: sessionHandler.js
// sentTokenCookie creates a cookie which expires after one day
const sendUserIdCookie = (userId, res) => {
// Our token expires after one day
const oneDayToSeconds = 24 * 60 * 60;
res.cookie('userId', userId,
{ maxAge: oneDayToSeconds,
// You can't access these tokens in the client's javascript
httpOnly: true,
// Forces to use https in production
secure: process.env.NODE_ENV === 'production'? true: false
});
};
Getting Cookies in Express
A great utility is cookie-parser
. You can use it to attach a new interface to your Express Request
and Response
instances. It is an extremely simple library and I highly recommend you check out the source code.
For learning purposes, we’ll use as few libraries as we can. But in your project you should use libraries like express-cookie
to read the request’s cookies, express-session
to manage sessions and || or
cookie-parser
to parse cookies.
Module: sessionHandler.js
// returns an object with the cookies' name as keys
const getAppCookies = (req) => {
// We extract the raw cookies from the request headers
const rawCookies = req.headers.cookie.split('; ');
// rawCookies = ['myapp=secretcookie, 'analytics_cookie=beacon;']
const parsedCookies = {};
rawCookies.forEach(rawCookie=>{
const parsedCookie = rawCookie.split('=');
// parsedCookie = ['myapp', 'secretcookie'], ['analytics_cookie', 'beacon']
parsedCookies[parsedCookie[0]] = parsedCookie[1];
});
return parsedCookies;
};
// Returns the value of the userId cookie
const getUserId = (req, res) => getAppCookies(req, res)['userId'];
Now that we know how to create and read session cookies, let’s create some sessions.
Unique Session IDs
In my opinion, the best tool in Node.js to get unique identifiers is the uuid
package. We’ll assign one unique identifier to each client.
Module: sessionHandler.js
// Our application store is stateful and uses a variable
const sessions = {};
const sessionHandler = (req, res, next)=> {
// extracting the user id from the session
let userId = getUserId(req, res);
// If we don't have a userId or the session manager doesn't recognize the userId
// then we create a new one one
if(!userId || !sessions[userId]) {
// this should create a time based unique identifier
userId = uuidv1();
sessions[userId] = {
cart: {}
};
// Clearing the cookies in case the session userid is not valid
res.clearCookie('userId');
// Returning the newly assigned cookie value
sendUserIdCookie(userId, res);
}
req.session = sessions[userId];
// Now in our route handlers you'll have session information in req.session
next();
};
Writing Our Shopping Routes
Here’s the route definitions for our cart:
Module: apiRouter.js
router.get('/cart', (req, res) => {
// Returns the value of the cart
const cart = req.session.cart;
res.status(200).send(cart);
});
router.post('/cart', (req, res) => {
const cart = req.session.cart;
const productName = req.body.productName;
// Fancy stupid trick to do create a key with the value 1
// or if the key exists increment the value by 1
cart[productName] = -~ cart[productName];
return res.status(200).send('success');
});
router.post('/checkout', (req, res)=> {
// We want to clear the cookies
res.clearCookie('userId');
});
module.exports = router;
You might have noticed that the application’s management is stateful. This means that if the server reloads we loose all of our sessions. That’s why we’ll want to use JWT tokens or Redis to make it stateless.
??? That's it for today! Feel free to ask us questions on Twitter. ???
This content originally appeared on Alligator.io and was authored by Alligator.io
Alligator.io | Sciencx (2020-03-26T00:00:00+00:00) Sending and Receiving Cookies from Express.js. Retrieved from https://www.scien.cx/2020/03/26/sending-and-receiving-cookies-from-express-js/
Please log in to upload a file.
There are no updates yet.
Click the Upload button above to add an update.