Search code examples
expressjwtexpress-router

Can't validate token in middleware JWT EXPRESS


I have a problem with the validation of JWT tokens. When I make a GET request from postman the validation isn't working. The request can work with no token. The question is what if I want to use this validation on middleware? What's wrong with my code?

customerController :


    authenticate: async(req,res) => {
            var email = req.body.email
            var password = req.body.password
            let emailAuth = await customer.email_auth(email) 
            if(!emailAuth){
                return res.status(500).json({status: "Failed", message:"User not found"});
            }else if(emailAuth.password != password){
                return res.status(500).json({status: "Failed", message:"Authentication failed. Wrong password."});
            }else{
                const payload = {
                    user : emailAuth.id
                };
                // console.log(payload)
                var token = jwt.sign(payload, app.get('superSecret'),{
                    expiresIn: 60 // 1menit
                });

                // return information incl token on json
                res.json({
                    success: true,
                    message: token,
                    // token: token
                })
            }

        }

users.js :


     router.use(function(req,res,next){
            var token = req.body.token || req.query.token || req.headers['x-access-token'];

            if(token){
                jwt.verify(token, app.get('superSecret'), function(err,decoded){
                    if(err){
                        return res.json({success: false, message: 'Failed to authenticate token.'})
                    }else{
                        req.decoded = decoded
                        next()
                    }
                })
            }else{
                return res.status(403).send({ 
                    success: false, 
                    message: 'No token provided.' 
                });
            }
        }) 

app.js :


    const express = require('express');
    const jwt = require('jsonwebtoken')
    const app = express();
    const bodyParser = require('body-parser');
    const router = require('./app/routes/users')

    // Route
    app.use(bodyParser())
    app.use('/users', router)


    //// server listening
    const port = process.env.PORT || 3000;
    app.listen(port)
    console.log(`server listening at ${port}`);


Solution

  • You need to create a middleware with your code and add it to routes which you want to be accessed by logged in users only.

    Here is your middleware: verifyToken

    var jwt = require('jsonwebtoken');
    function verifyToken(req, res, next) {
      var token = req.body.token || req.query.token || req.headers['x-access-token'];
    
      if(token){
        jwt.verify(token, app.get('superSecret'), function(err,decoded){
          if(err){
            return return res.status(403).send({ 
              success: false, 
              message: 'Failed to authenticate.' 
            });
          }else{
            req.decoded = decoded
            next()
          }
        })
      }else{
        return res.status(403).send({ 
          success: false, 
          message: 'No token provided.' 
        });
      }
    }
    module.exports.verifyToken = verifyToken;
    

    Now in your app.js you can add this verifyToken middleware to /users route.

    const express = require('express');
    const app = express();
    const bodyParser = require('body-parser');
    const router = require('./app/routes/users')
    const verifyToken = require('./your-middleware-path')
    
    // Route
    app.use(bodyParser())
    app.use('/users', verifyToken, router)
    
    
    //// server listening
    const port = process.env.PORT || 3000;
    app.listen(port)
    console.log(`server listening at ${port}`);