Building a Subscription System using Stripe, Node.js, and MongoDB - Part 4: Authorization

In this guide, we will give our paying customers access to premium content by implementing an Express Middleware.

Building a Subscription System using Stripe, Node.js, and MongoDB - Part 4: Authorization

This is the Part 4 in the series of guides on adding, managing, and keeping track of subscription payments using Stripe and Mongo for your SaaS app.

Introduction

Subscription Payments are the bread and butter of a SaaS application; it's how you start generating revenue. In a well-implemented system, users need to first be able to change or cancel their plans, and second, undergo a trial phase to see if they would even like to pay for premium features. Typically, it's a hassle to set these up. In this set of guides, we will go through all the steps required to build a complete Subscription Payments system for your SaaS app.

In Part 4, we will:

  1. Set up an express middleware to extract user information from every request
  2. Allow customers to access content based on their plan - None, Basic, Pro

Add Plan-Specific content

Let's create links to three different pages that will house their own content.

<p>You can access your content by clicking one of the buttons below.</p>
<ul>
	<li><a href="/none">None</a></li>
	<li><a href="/basic">Basic</a></li>
	<li><a href="/pro">Pro</a></li>
</ul> 

Set Current User Middleware

Currently, for any request made to our server from the client, we have to extract the customer information and get the full profile from the database. Following DRY (Don't Repeat Yourself), we can offload this work to a middleware function in Node.

src/middleware/setCurrentUser.js

const UserService = require('../user')

module.exports = async function setCurrentUser (req, res, next) {
  const { email } = req.session

  if (email) {
    user = await UserService.getUserByEmail(email)

    req.user = user
    next()
  } else {
    res.redirect('/')
  }
}

We can set up another middleware to figure out what plan the customer is currently on.

src/middleware/hasPlan.js

module.exports = function hasPlan (plan) {
  return async (req, res, next) => {
    if (req.user && req.user.plan == plan) {
      next()
    } else {
      res.status(401).send('Unauthorized')
    }
  }
}

We are now ready to use our middlewares and make our code easier to read.

app.js

const setCurrentUser = require('./src/middleware/setCurrentUser')
const hasPlan = require('./src/middleware/hasPlan')

//...

app.get('/none', [setCurrentUser, hasPlan('none')], async function (
  req,
  res,
  next
) {
  res.status(200).render('none.ejs')
})

app.get('/basic', [setCurrentUser, hasPlan('basic')], async function (
  req,
  res,
  next
) {
  res.status(200).render('basic.ejs')
})

app.get('/pro', [setCurrentUser, hasPlan('pro')], async function (
  req,
  res,
  next
) {
  res.status(200).render('pro.ejs')
})

Test it out

  1. Subscribe to the Basic plan
  2. Try to access the /pro endpoint - Unauthorized
  3. Now try to access the /basic endpoint - Success!

Next Steps

In this guide, we learned how to:

  1. Set up an express middleware to extract user information from every request
  2. Allow customers to access content based on their plan - None, Basic, Pro

Our subscription payments system is mostly complete. But before we can deploy it to Production, we have to make some changes - use a cloud DB, set up the production webhook and more. This is what we will tackle in the next part.

Didn't find this guide useful? Let me know