Node.js Custom Authentication Series: Starting with Sessions in Express.js
Tags: Postgres, Session Management, Expressjs, Connecg Pg Simple, Express Session

just a random pic for your pleasure

Series Introduction:

In this series we will explore custom authentication in Node.js with Express, Express-Session, Postgress and connect-pg-simple.

NOTE: We will not be using any authentication frameworks such as Passport. Everything will be built from scratch.

What You Need: A basic understand of how Restful APIs work, prior exposure to Express.js, a basic understanding databases, a basic understanding of SQL, A Postgres database (Heroku is best free option) and some coffee.

Step 1:Preamble

A. Create Heroku account

B.set up a Postgres database.

C. Connect to your database from a command line tool (terminal on Mac and Linux, you figure out for Windows)

D. Once you connect to your database, run the following script to create a database table to store your session information. (copy, paste, press enter)

CREATE TABLE "session" ( "sid" varchar NOT NULL COLLATE "default", "sess" json NOT NULL, "expire" timestamp(6) NOT NULL)WITH (OIDS=FALSE);ALTER TABLE "session" ADD CONSTRAINT "session_pkey" PRIMARY KEY ("sid") NOT DEFERRABLE INITIALLY IMMEDIATE;

Step 2:Preamble Part 2

At this stage, we’re ready to create our Express server, or add session management to existing server.

Create an express server by running the command: express <servername> i.e express sessionexample

This will create an express boilerplate with that name.

Next cd into <servername> i.e sessionexample and run: npm install

This will install all the packages that come with the boilerplate.

Next, we will the session management packages. To do this, run:

npm i express-session connect-pg-simple pg body-parser cors

Express-session is a session management middleware for express.js maintained by the express team. connect-pg-simple is an npm package that allows you to store session information in a postgres database instead of Reddis. PG is an npm package for postgres database connectivity, it allows you connect to, and operate a postgres database. Body-parser is an request data parser for express maintained by the express team. Cors is an npm package for managing cross origin resource sharing for express and connect servers.

Step 3:Connecting To Your Database

Next we will create a connection pool using the pg module.

A: Create a folder called db in your project root folder

B: Create a file called index.js in your db folder and enter the following code

const { Pool } = require('pg'); const pool = new Pool({ uri: "", host: "", user: "", database: "", password: "", port: "", ssl: true }) module.exports = { getPool(){ return pool

}, }

/*

1. import Pool class from the pg module, which pools and efficiently manages connections to the database

2. Provide the database credentials

3. Export the connection pool */

C: Get the database credentials for your postgres database, and enter them in the correct fields

NOTE: Use environment variables (use the dotenv module), never insert passwords and usernames… in your code, except if this database and code is just for learning (i.e class work where the database holds nothing of value)

Step 4:Put It Together

Next open your app.js file and make sure that the order of your code looks exactly like this, each line should appear in the exact order that the code below appears

var createError = require('http-errors'); var express = require('express'); var app = express(); var bodyParser = require('body-parser') var path = require('path'); var cookieParser = require('cookie-parser'); var session = require('express-session') var logger = require('morgan'); var indexRouter = require('./routes/index'); var usersRouter = require('./routes/users'); var pgSession = require('connect-pg-simple')(session) var pool = require('./db/index').getPool() var cors = require('cors') // view engine setup app.set('views', path.join(__dirname, 'views')); app.set('view engine', 'jade'); app.use(cors({origin:true,credentials: true})) app.use(logger('dev')); app.use(express.json()); app.use(express.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use(bodyParser.urlencoded({extended:false})) app.use(bodyParser.json()) app.use(session( { store: new pgSession({ pool : pool, // Connection pool tableName: 'session' }), secret: '', ////////PROVIDE A SECRET/////USE ENVIRONMENT VARIABLES, UNLESS THIS IS FOR HOMEWORK OR SOMETHING SIMILAR OF NO IMPORTANCE resave: true, cookie: { secure: false, maxAge: 30 * 24 * 60 * 60 * 1000 }, // 30 days saveUninitialized: true, } )) app.use('/', indexRouter); app.use('/users', usersRouter); // catch 404 and forward to error handler app.use(function(req, res, next) { next(createError(404)); }); // error handler app.use(function(err, req, res, next) { // set locals, only providing error in development res.locals.message = err.message; res.locals.error = req.app.get('env') === 'development' ? err : {}; // render the error page res.status(err.status || 500); res.render('error'); }); module.exports = app;

NOTE: It’s very important that your code follows the same order as this code above, if you change the order, your server will fail!

NOTE: It’s also important that you provide a “secret” for your cookie. This is just a random string, make sure it’s long for security.

Step 5:Confirmation

At this point, we have completed setting up sessions and session storage with postgres. The last step is to confirm everything. To do that, open your index.js file in your routes folder and past in the following code.

router.get('/test', function(req, res, next) { res.send(req.session); console.log(req.session) });

Next, navigate to localhost:3000/test in your browser and you should see something that looks like this:

{"cookie":{"originalMaxAge":2591999997,"expires":"2019-09-11T15:33:49.197Z","secure":false,"httpOnly":true,"path":"/"},"user":"ibra"}

If you see that, congratulations!

Otherwise, scroll backup and check what you missed.

Below is a boilerplate for express-session with postgres using connect-pg-simple with dotenv

NOTE: Make sure you follow this blog for more useful articles, boilerplates and even new NPM PACKAGES! (I’m developing one right now)