¿Cómo saber si el usuario inició sesión con passport.js?

104

He estado leyendo passport.jsinformación y muestras durante dos días, pero no estoy seguro de haber realizado todo el proceso de autenticación.

¿Cómo sé si he iniciado sesión? Por ejemplo, tendré una barra de navegación con un botón de inicio de sesión o cierre de sesión, ¿hay alguna variable como el código a continuación?

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

Respuestas:

210

Si el usuario está conectado, passport.jscreará un userobjeto reqpara cada solicitud express.js, que puede verificar su existencia en cualquier middleware:

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

Puede crear un express.jsmiddleware simple para eso, que verificará si el usuario ha iniciado sesión y, de lo contrario, lo redireccionará a la /loginpágina:

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

Y úsalo:

app.get('/orders', loggedIn, function(req, res, next) {
    // req.user - will exist
    // load user orders and render them
});
moka
fuente
¿Es global? ¿Puedo acceder a él en todos los proyectos después de iniciar sesión?
RMontes13
3
no es global, solo está en el objeto de solicitud.
supernova
1
En el 98,8% del desarrollo web con express.js y passport.js, se ocupará de las solicitudes (app.get, app.post, etc.), por lo que hablar sobre el uso de passport.js fuera de él no tiene sentido. Sí, solo está dentro de los controladores de middleware de ruta rápida como app.get, app.postetc. Si necesita una funcionalidad diferente, debe explicarla en detalle en su pregunta, así como lo que está tratando de lograr.
moka
2
Descubrí que si no proporciono router.get () con ningún middleware para verificar la autenticación, como en "router.get ('/', my_controller.index)", nunca se consulta el pasaporte y req.user siempre ser indefinido. Esto es frustrante porque quiero permitir que cualquier visitante llame a una API, pero adapte el contenido de la respuesta según quién la solicite.
Lawrence I. Siden
2
¿Alguien puede explicar cómo esto no es explotable? Esa verificación simplemente busca ver si hay un objeto de usuario en la solicitud. ¿Dónde está la validación de la sesión?
rambossa
46

Si desea usarlo en sus plantillas, ya que su ejemplo de código parece indicar, puede crear algún middleware como este:

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

Coloque ese código en algún lugar después de haber configurado el pasaporte.

Y luego úselo en su plantilla (ejemplo de trago)

{% if login %}
<button>logout</button>
{% else %} 
<button>login</button>
{% endif %}
ciberwombat
fuente
Por alguna razón, el middleware anterior me estaba dando un problema con el usuario no definido en mi plantilla. Tuve que volver a suministrar el objeto de usuario a la vista para arreglarlo así: app.use(function(req,res,next){ res.locals.login = req.isAuthenticated(); res.locals.user = req.user; next(); });
Tebbers
Incluso después de una autenticación exitosa, isAuthenticatedda falso en la siguiente solicitud. ¿Podría ayudarme a responder esta pregunta? Stackoverflow.com/questions/42842171/…
Suhail Gupta
3

No se documenta explícitamente pero hay un isAuthenticated()método que se inserta en reqpor pasaporte .
Se puede utilizar de la siguiente manera,

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

Estaba buscando esa solución y encontré esta página. La pregunta es cómo verificar el estado de inicio de sesión en el lado del cliente.

Después de iniciar sesión, oculto el botón Iniciar sesión y muestro el botón Cerrar sesión. En la actualización de la página, vuelvo a ver el botón de inicio de sesión en lugar del botón de cierre de sesión. La única solución es guardar un elemento en sessionStorage si está usando session (y localStorage si está usando JWT). Elimine este elemento cuando cierre la sesión. Luego, en cada carga de la página, verifique este elemento de sessionStorage y hágalo en consecuencia.

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

use el siguiente código dentro de app.get () o router.get ()

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

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

Buena pregunta, tuve algunos problemas al intentar implementar algo como esto, cuando hay una solicitud no autenticada, el manillar omite el bloque if si la variable res.locals devuelve un valor falso. Para resolver este problema, debe configurar un middleware en su archivo app.js para que req.user esté disponible globalmente en su aplicación.

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

});

En su archivo de encabezado, puede hacer esta verificación para el usuario autenticado y mostrar el contenido de acuerdo 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
fuente