Comment savoir si l'utilisateur est connecté avec passeport.js?

104

Je lis des passport.jsinformations et des échantillons depuis deux jours, mais je ne suis pas sûr qu'après cela, j'ai fait tout le processus d'authentification.

Comment savoir si je suis connecté, par exemple, j'aurai une barre de navigation avec un bouton de connexion ou de déconnexion, y a-t-il une variable comme le code ci-dessous?

if (login)
   <button>logout</button>
else 
   <button>login</button>
RMontes13
la source

Réponses:

210

Si l'utilisateur est connecté, passport.jscréera un userobjet reqpour chaque demande express.js, dont vous pouvez vérifier l'existence dans n'importe quel middleware:

if (req.user) {
    // logged in
} else {
    // not logged in
}

Vous pouvez créer un express.jsmiddleware simple pour cela, qui vérifiera si l'utilisateur est connecté et, sinon, redirigera vers la /loginpage:

function loggedIn(req, res, next) {
    if (req.user) {
        next();
    } else {
        res.redirect('/login');
    }
}

Et utilisez-le:

app.get('/orders', loggedIn, function(req, res, next) {
    // req.user - will exist
    // load user orders and render them
});
moka
la source
C'est global? Puis-je y accéder dans tous les projets après la connexion?
RMontes13
3
ce n'est pas global, c'est juste sur l'objet de requête.
supernova le
1
Dans 98,8% du développement Web avec express.js et passport.js, vous traiterez des demandes (app.get, app.post, etc.), donc parler d'utiliser passport.js en dehors de celui-ci est un peu inutile. Oui, ce n'est que dans les gestionnaires de middleware de route express comme app.get, app.postetc. Si vous avez besoin de fonctionnalités différentes, vous devriez l'expliquer en détail dans votre question ainsi que ce que vous essayez d'atteindre.
moka le
2
J'ai trouvé que si je ne fournis à router.get () aucun middleware pour vérifier l'authentification, comme dans "router.get ('/', my_controller.index)", alors le passeport n'est jamais consulté et req.user sera toujours être indéfini. C'est frustrant car je souhaite autoriser n'importe quel visiteur à appeler une API, mais adapter le contenu de la réponse en fonction de la personne qui la demande.
Lawrence I. Siden
2
Quelqu'un peut-il expliquer en quoi cela n'est pas exploitable? Ce contrôle cherche simplement à voir s'il s'agit d'un objet utilisateur dans la requête. Où est la validation de session?
rambossa
46

Si vous souhaitez l'utiliser dans vos modèles, comme votre exemple de code semble l'indiquer, vous pouvez créer un middleware tel que celui-ci:

app.use(function (req, res, next) {
  res.locals.login = req.isAuthenticated();
  next();
});

Placez ce code quelque part après avoir configuré le passeport.

Et puis utilisez-le dans votre modèle (exemple de swig)

{% if login %}
<button>logout</button>
{% else %} 
<button>login</button>
{% endif %}
cyberwombat
la source
Pour une raison quelconque, le middleware ci-dessus me posait un problème avec l'utilisateur non défini dans mon modèle. J'ai dû fournir à nouveau l'objet utilisateur à la vue pour le corriger comme app.use(function(req,res,next){ res.locals.login = req.isAuthenticated(); res.locals.user = req.user; next(); });
suit
Même après une authentification réussie, isAuthenticateddonne false dans la prochaine requête. Pourriez-vous aider à répondre à cette question stackoverflow.com/questions/42842171/…
Suhail Gupta
3

Ce n'est pas explicitement documenté mais il existe une isAuthenticated()méthode qui est insérée reqpar passeport .
Peut être utilisé comme suit,

req.isAuthenticated() // returns true if auth, false if not

// auth.js
module.exports = {
  ensureAuthenticated: (req, res, next) => {
    if (req.isAuthenticated()) {
      return next()
    }
    res.redirect('/login') // if not auth
  },

  forwardAuthenticated: (req, res, next) => {
    if (!req.isAuthenticated()) {
      return next()
    }
    res.redirect('/dashboard');  // if auth    
  }
}

// app.js
app.get('/dashboard', ensureAuthenticated, (req, res) => res.render('dashboard'))
app.get('/login', forwardAuthenticated, (req, res) => res.render('login'))
app.get('/register', forwardAuthenticated, (req, res) => res.render('register'))
Hasan Sefa Ozalp
la source
2

Je cherchais une telle solution et suis tombé sur cette page. La question est de savoir comment vérifier l'état de connexion côté client.

Après la connexion, je cache le bouton de connexion et affiche le bouton de déconnexion. Lors de l'actualisation de la page, je vois à nouveau le bouton de connexion au lieu du bouton de déconnexion. La seule solution consiste à enregistrer un élément dans sessionStorage si vous utilisez session (et localStorage si vous utilisez JWT). Supprimez cet élément lorsque vous vous déconnectez. Ensuite, à chaque chargement de page, vérifiez cet élément sessionStorage et procédez en conséquence.

if (sessionStorage.getItem('status')) {
    $("#btnlogout").show();
    $("#btnlogin").hide();
// or what ever you want to do
} else {
    $("#btnlogout").hide();
    $("#btnlogin").show();
}



function Login() {
            var data = {
                username: $("#myModal #usr").val(),
                password: $("#myModal #pw").val()

            };
            $.ajax({
                type: 'POST',
                url: '/login',
                contentType: 'application/JSON; charset=utf-8',
                data: JSON.stringify(data),
                success: funcSuccess,
                error: funcFail
            });
            function funcSuccess(res) {
                sessionStorage.setItem('status', 'loggedIn');

                $("#btnlogout").show();
                $("#btnlogin").hide();
            }
            function funcFail() { $("#pp").text('Login Failed'); };
        };

function Logout() {
    $.ajax({
        type: 'GET',
        url: '/logout',
        contentType: 'application/JSON; charset=utf-8',
        success: funcSuccess,
        error: funcFail,
    });
    function funcSuccess(res) {
        $("#btnlogout").hide();
        $("#btnlogin").show();
        sessionStorage.removeItem("status");
    };
    function funcFail() { alert('Login method Failed'); };
}; 
Zeni
la source
2

utilisez le code ci-dessous dans app.get () ou router.get ()

router.get('/edit/:id', (req, res)=>{
  if(req.isAuthenticated()){
     if(req.isAuthenticated()){
      //

      }
  else{
   res.redirect('/users/login');//your particular login routes
     }
});
Pankaj
la source
0

Bonne question, j'ai eu quelques problèmes en essayant d'implémenter quelque chose comme ça, quand il y a une demande non authentifiée, le guidon ignore le bloc if si la variable res.locals renvoie une valeur falsifiée. Pour résoudre ce problème, vous devez configurer un middleware dans votre fichier app.js pour rendre le req.user disponible globalement dans votre application.

app.use(function (req, res, next) {
res.locals.login = req.user;
next();

});

Dans votre fichier d'en-tête, vous pouvez effectuer cette vérification pour l'utilisateur authentifié et afficher le contenu en conséquence.

                {{#if login }}
                    <li><a href="#">User Account</a></li>
                    <li role="separator" class="divider"></li>
                    <li><a href="#">Logout</a></li>
                {{/if}}
                {{#unless login}}
                    <li><a href="#">Sign up</a></li>
                    <li><a href="#">Sign in</a></li>
                {{/unless}} 
Camillus Chinaedu Teteh
la source