Search code examples
node.jsrestexpresspassport.jsrestful-authentication

Special Passport Authentication for Specific Route


I'm developing a RESTful API with Express.js and I'm using Passport.js for authentication purposes.
Here is an example of how I'm using passport with routes:

const beerRoutes = require('./beerRoutes')     // an instance of express router
let authenticateRoute = passport.authenticate('jwt', { session: false })

router.use('/beer', authenticateRoute, beerRoutes)

Inside beerRoutes.js :

const router = require('express').Router()

router.post('/', (req, res) => {})
router.get('/', (req, res) => {})
router.patch('/', (req, res) => {})
router.delete('/', (req, res) => {})

The problem is, I want unauthenticated clients to be able to create new users (i.e. POST /beer/). But I also want to give additional permissions to authenticated clients when they send a request to the same endpoint.

How can I achieve this without letting unauthenticated clients to access other routes inside beerRoutes (e.g. PATCH /beer/)?


Solution

  • This can be addressed with a custom middleware which calls the Passport.js middleware.

    const authenticationWhiteList = [
      'POST /beer'
    ]
    
    
    function Authenticate (request, response, next) {
      let route = `${request.method} ${request.baseUrl}`
    
      if (_.indexOf(authenticationWhiteList, route) !== -1) {
        next()
      } else {
        passport.authenticate('jwt', { session: false })(request, response, next)
      }
    }
    

    Then change the authentication code to this one:

    const beerRoutes = require('./beerRoutes')     // an instance of express router
    
    // let authenticateRoute = passport.authenticate('jwt', { session: false })
    let authenticateRoute = Authenticate
    
    
    router.use('/beer', authenticateRoute, beerRoutes)