Como saber se o usuário está logado com passport.js?

104

Estou lendo passport.jsinformações e amostras há dois dias, mas não tenho certeza se depois disso fiz todo o processo de autenticação.

Como posso saber se estou logado, por exemplo, terei uma barra de navegação com um botão de login ou logout, existe alguma variável como o código abaixo?

if (login)
   <button>logout</button>
else 
   <button>login</button>
RMontes13
fonte

Respostas:

210

Se o usuário estiver logado, passport.jscriará um userobjeto reqpara cada solicitação express.js, que pode ser verificada em qualquer middleware:

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

Você pode criar um express.jsmiddleware simples para isso, que verificará se o usuário está conectado e, se não estiver, redirecionará para a /loginpágina:

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

E use-o:

app.get('/orders', loggedIn, function(req, res, next) {
    // req.user - will exist
    // load user orders and render them
});
moka
fonte
É global? Posso acessá-lo em todos os projetos após o login?
RMontes13
3
não é global, é apenas no objeto de solicitação.
supernova
1
Em 98,8% do desenvolvimento web com express.js e passport.js você lida com solicitações (app.get, app.post, etc), então falar sobre o uso de passport.js fora dele é um pouco inútil. Sim, é apenas em manipuladores de middleware de rota expressa app.get, como app.postetc. Se você precisar de uma funcionalidade diferente, deve explicá-la em detalhes em sua pergunta, bem como o que você está tentando alcançar.
moka
2
Descobri que, se não fornecer a router.get () nenhum middleware para verificar a autenticação, como em "router.get ('/', my_controller.index)", o passaporte nunca será consultado e req.user sempre será ser indefinido. Isso é frustrante porque desejo permitir que qualquer visitante chame uma API, mas adaptar o conteúdo da resposta dependendo de quem está solicitando.
Lawrence I. Siden
2
Alguém pode explicar como isso não é explorável? Essa verificação apenas verifica se o seu é um objeto de usuário na solicitação. Onde está a validação da sessão?
rambossa
46

Se desejar usá-lo em seus modelos, já que seu exemplo de código parece indicar, você pode criar algum middleware como este:

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

Coloque esse código em algum lugar depois de configurar o passaporte.

E, em seguida, use-o em seu modelo (exemplo de gole)

{% if login %}
<button>logout</button>
{% else %} 
<button>login</button>
{% endif %}
cyberwombat
fonte
Por alguma razão, o middleware acima estava me dando um problema com o usuário ser indefinido em meu modelo. Tive que fornecer novamente o objeto de usuário para a visualização para corrigi-lo assim: app.use(function(req,res,next){ res.locals.login = req.isAuthenticated(); res.locals.user = req.user; next(); });
Tebbers
Mesmo após autenticação com sucesso, isAuthenticateddá falso na próxima solicitação. Você poderia ajudar a responder a esta pergunta stackoverflow.com/questions/42842171/…
Suhail Gupta
3

Não está documentado explicitamente, mas existe um isAuthenticated()método que é inserido reqpor passaporte .
Pode ser usado da seguinte maneira,

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
fonte
2

Eu estava procurando essa solução e me deparei com esta página. A questão é como verificar o status de login no lado do cliente.

Depois de fazer o login, oculto o botão Login e mostro o botão de logout. Na atualização da página, vejo novamente o botão de login em vez do botão de logout. A única solução é salvar um item em sessionStorage se você estiver usando sessão (e localStorage se você estiver usando JWT). Exclua este item ao fazer logout. Então, em cada carregamento de página, verifique este item sessionStorage e faça de acordo.

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
fonte
2

use o código abaixo dentro de 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
fonte
0

Boa pergunta, tive alguns problemas ao tentar implementar algo assim, quando há uma solicitação não autenticada, o guidão pula o bloco if se a variável res.locals retornar um valor falso. Para resolver esse problema, você precisa configurar um middleware em seu arquivo app.js para tornar o req.user disponível globalmente em seu aplicativo. Assim ..

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

});

Em seu arquivo de cabeçalho, você pode fazer esta verificação para usuários autenticados e exibir de acordo com o conteúdo como tal.

                {{#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
fonte