Noah Blues
Noah Blues

Reputation: 1359

How to use the middleware to check the authorization before entering each route in express?

I want to check the authorization of the users of my web app when they entered the url. But when I used an individually middleware to check the authorization, it's useless for the already existing routes, such as:

function authChecker(req, res, next) {
    if (req.session.auth) {
        next();
    } else {
       res.redirect("/auth");
    }
}

app.use(authChecker);
app.get("/", routes.index);
app.get("/foo/bar", routes.foobar);

The authChecker is unabled to check the authority of the users who entered the two urls. It only works for the unspecified urls.

And I saw a method that I can put the authChecker between the route and the route handler, such as:

app.get("/", authChecker, routes.index);

But How can I achieve it in a simple way rather than putting the authChecker in every route?

Upvotes: 43

Views: 47172

Answers (3)

guydog28
guydog28

Reputation: 1317

As long as

app.use(authChecker);

is before

app.use(app.router);

it will get called for every request. However, you will get the "too many redirects" because it is being called for ALL ROUTES, including /auth. So in order to get around this, I would suggest modifying the function to something like:

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

This way you won't redirect for the auth url as well.

Upvotes: 44

sintaxi
sintaxi

Reputation: 1868

There are may ways to approach this problem but here is what works for me.

I like to create an array of middleware for protected and unprotected routes and then use when necessary.

var protected   = [authChecker, fetchUserObject, ...]
var unprotected = [...]

app.get("/", unprotected, function(req, res){
  // display landing page
})

app.get("/dashboard", protected, function(req, res){
  // display private page (if they get this far)
})

app.get("/auth", unprotected, function(req, res){
  // display login form
})

app.put("/auth", unprotected, function(req, res){
  // if authentication successful redirect to dashboard
  // otherwise display login form again with validation errors
})

This makes it easy to extend functionality for each middleware scopes by editing the array for each type of route. It also makes the function of each route more clear because it tells us the type of route it is.

Hope this helps.

Upvotes: 30

Peter Lyons
Peter Lyons

Reputation: 145994

But when I used an individually middleware to check the authorization, it's useless for the already existing routes

Express will run middleware in the order added to the stack. The router is one of these middleware functions. As long as you get your authChecker into the stack BEFORE the router, it will be used by all routes and things will work.

Most likely you have the router before authChecker because you have routes defined prior to getting your authChecker into the stack. Make sure to put all your app.use calls before any calls to app.get, app.post, etc to avoid express's infuriating implicit injection of the router into the middleware stack.

Upvotes: 2

Related Questions