M Ansyori
M Ansyori

Reputation: 488

Unable to Apply Middleware to Router in ExpressJS?

I have an app where I have public routes and authenticated routes. isAuthenticated were applied for example to a news controller.

globalRouter: function (app) {
  app.use((req, res, next) => {
    logger.log("Endpoint: ", req.originalUrl);
    next();
  });
  const userRouter = require("./user/controller");
  const globalRouter = require("./global/controller");
  const newsRouter = require("./news/controller");

  app.use("/user", userRouter);
  app.use("/global", globalRouter);
  app.use("/news", middleware.isAuthenticated(), newsRouter); // here
}

And here is the isAuthenticated code written in middleware.js file.

const security = require("../utils/security");
const service = require("../user/service");

exports.isAuthenticated = function (req, res, next) {
  let authorization = req.headers.authorization;
  let token = null;
  if (authorization.startsWith("Bearer ")) {
    token = authorization.substring(7, authorization.length);
    if (token !== null) {
      service.checkUserTokenMiddleware(token, security).then((response) => {
        console.log("checkUserTokenMiddleware", response);
        if (response) {
          next();
        }
      });
    }
  }
};

The problem is that I'm getting this error below when I npm start the app

TypeError: Cannot read property 'headers' of undefined at Object.exports.isAuthenticated

What am I missing here?

why do I get such an error meanwhile in my other file using the same method like req.body.blabla or req.headers.blabla is fine?

Any help will be much appreciated.

Regards.

Upvotes: 0

Views: 133

Answers (2)

xdeepakv
xdeepakv

Reputation: 8125

It depends on how you import, middleware.js. Since you are exporting, isAuthenticated as function. This should be not called before passing to app.use.

Other things to be noticed, you never call the next function on error or else.

Please have a look in the below example.

// middleware.js

const security = require("../utils/security");
const service = require("../user/service");

exports.isAuthenticated = function (req, res, next) {
  let authorization = req.headers.authorization;
  let token = null;
  if (authorization.startsWith("Bearer ")) {
    token = authorization.substring(7, authorization.length);
    if (token !== null) {
      service
        .checkUserTokenMiddleware(token, security)
        .then((response) => {
          if (response) {
            next();
          }
        })
        .catch((error) => next(error));
    } else {
      next("UNAUTHORIZED");
    }
  } else {
    next("UNAUTHORIZED");
  }
};

// app.js

const middleware = require("./middleware")

app.use((req, res, next) => {
  logger.log("Endpoint: ", req.originalUrl);
  next();
});
const userRouter = require("./user/controller");
const globalRouter = require("./global/controller");
const newsRouter = require("./news/controller");

app.use("/user", userRouter);
app.use("/global", globalRouter);
app.use("/news", middleware.isAuthenticated, newsRouter); // here

Upvotes: 0

user7896971
user7896971

Reputation:

Simply remove the brackets after the function call:

app.use("/news", middleware.isAuthenticated, newsRouter);

You don't have to call the function in the callback to app.use, Express will itself pass in req,res,next to the auth function and call it.

Upvotes: 2

Related Questions