Categories
Node.js Tips

Node.js Tips — Testing Redirects, Sessions, and Auth Middlewares

Spread the love

Like any kind of apps, there are difficult issues to solve when we write Node apps.

In this article, we’ll look at some solutions to common problems when writing Node apps.

Use the Middleware to Check the Authorization Before Entering Each Route in Express

We can add a middleware to a route to check for the proper credentials before entering a route.

For instance, we can write:

const protectedMiddlewares = [authChecker, fetchUser];
const unprotectedMiddlewares = [trackVisistorCount];

app.get("/", unprotectedMiddlewares, (req, res) => {
  //...
})

app.get("/dashboard", protectedMiddlewares, (req, res) => {
  // ...
})

app.get("/auth", unprotectedMiddlewares, (req, res) => {
  //...
})

app.put("/auth", unprotectedMiddlewares, (req, res) => {
  //...
})

We have an array of middleware for the protected dashboard route.

And we have an array of middleware for the unprotected routes.

A middleware may look like the following:

const authChecker = (req, res, next) => {
  if (req.session.auth || req.path === '/auth') {
    next();
  } else {
    res.redirect("/auth");
  }
}

We have the authChecker middleware that checks the path of the route and the session.

If there’s a session set, then we call the next middleware which should lead to a protected route handler in the end.

Otherwise, we redirect to the auth route.

Testing Requests that Redirect with Mocha and Supertest in Node

To test requests that redirect to another route with Supertest running in the Mocha test runner, we can write;

it('should log out the user', (done) => {
  request(app)
    .post('/login')
    .type('form')
    .field('user', 'username')
    .field('password', 'password')
    .end((err, res) => {
      if (err) { return done(err); }
      request(app)
        .get('/')
        .end((err, res) => {
          if (err) { return done(err); }
          res.text.should.include('profile');
          done();
        });
    });
});

We test a login route for redirection by checking the response text in the second end callback.

To do that, we made a POST request with the username and password.

Then that callback is called after the redirect is done.

We can get the text from the response to see if it’s the text in the profile route.

Send Additional HTTP Headers with Express

We can send whatever response headers we want with the setHeader method of the response object.

For instance, we can write:

app.use((req, res, next) => {
  res.setHeader("Access-Control-Allow-Origin", "*");
  return next();
});

We set the Access-Control-Allow-Origin to * to allow requests from all origins.

Working with Sessions in Express

To work with sessions in an Express app, we can use the expression-middleware.

For instance, we can use it by writing:

const express = require('express');
const session = require('express-session');

const app = express();

app.use(session({
  resave: false,
  saveUninitialized: false,
  secret: 'secret'
}));

app.get('/', (req, res) => {
  if (req.session.views) {
    ++req.session.views;
  } else {
    req.session.views = 1;
  }
  res.send(`${req.session.views} views`);
});

app.listen(3000);

We used the express-session package with a few options.

session is a function that returns a middleware to let us work with sessions.

resave means we don’t save a session if it’s not modified is it’s false .

saveUninitialized means that we don’t create a session until something is stored if it’s false .

secret is the secret for signing the sessions.

Then we can store whatever data we want in the req.session property.

It’ll persist until the session expires.

We just keep increasing the views count as we hit the / route.

The default is the memory store, which should only be used if we don’t have multiple instances.

Otherwise, we need to use persistent sessions.

Get the List of Connected Clients Username using Socket.io

We can get the list of clients connected to a namespace or not by using the clients method.

For instance, we can write:

const clients = io.sockets.adapter.rooms[roomId];
for (const clientId of Object.keys(clients)) {
  console.log(clientId);
  const clientSocket = io.sockets.connected[clientId];
}

We get an object with the client IDs as the keys with the io.socket.adapter.rooms object.

roomId is the ID of the room we’re in.

Then we can get the socket for the client with the io.socket.connected object.

Conclusion

We can get the clients with Socket.io.

Also, we can write our own middlewares to check for credentials before proceeding to the route.

express-session lets us work with sessions in our Express app.

We can test redirects with Supertest by checking the response content in the end callback.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *