web-dev-qa-db-fra.com

Comment utiliser le middleware pour vérifier l'autorisation avant d'entrer dans chaque itinéraire en express?

Je souhaite vérifier l'autorisation des utilisateurs de mon application Web lorsqu'ils ont saisi l'URL. Mais lorsque j'ai utilisé un middleware individuel pour vérifier l'autorisation, il est inutile pour les routes déjà existantes, telles que:

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);

authChecker n'est pas activé pour vérifier l'autorité des utilisateurs qui ont entré les deux URL. Cela ne fonctionne que pour les URL non spécifiées.

Et j'ai vu une méthode que je peux mettre le authChecker entre l'itinéraire et le gestionnaire d'itinéraire, comme:

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

Mais comment puis-je y parvenir d'une manière simple plutôt que de mettre l'authChecker dans chaque itinéraire?

32
Noah Blues

Aussi longtemps que

app.use(authChecker);

est avant

app.use(app.router);

il sera appelé pour chaque demande. Cependant, vous obtiendrez le "trop ​​de redirections" car il est appelé pour TOUTES LES ROUTES , y compris / auth. Donc, pour contourner cela, je suggère de modifier la fonction en quelque chose comme:

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

De cette façon, vous ne redirigerez pas l'URL d'authentification également.

32
guydog28

Il existe plusieurs façons d'aborder ce problème, mais voici ce qui fonctionne pour moi.

J'aime créer une gamme de middleware pour les itinéraires protégés et non protégés et les utiliser lorsque cela est nécessaire.

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
})

Cela facilite l'extension des fonctionnalités pour chaque portée de middleware en modifiant la baie pour chaque type de route. Il rend également la fonction de chaque itinéraire plus claire, car elle nous indique le type d'itinéraire qu'il s'agit.

J'espère que cela t'aides.

24
sintaxi

Mais quand j'ai utilisé un middleware individuel pour vérifier l'autorisation, il est inutile pour les routes déjà existantes

Express exécutera le middleware dans l'ordre ajouté à la pile. Le routeur est l'une de ces fonctions middleware. Tant que vous obtenez votre authChecker dans la pile AVANT le routeur, il sera utilisé par toutes les routes et les choses fonctionneront.

Vous avez probablement le routeur avant authChecker car vous avez défini des itinéraires avant de placer votre authChecker dans la pile. Assurez-vous de mettre tous vos app.use appels avant tout appel à app.get, app.post, etc. pour éviter l'injection implicite exaspérante du routeur dans la pile du middleware.

1
Peter Lyons