node.js - authenticate - Nodo+Express+Pasaporte: req.user Indefinido
passport js (16)
Mi pregunta es similar a esta, pero no hubo una idea de su solución.
Estoy usando Passport para autenticar usando Instagram. Después de la autenticación exitosa, los usuarios se dirigen a "/". En este punto, la solicitud tiene el objeto de usuario (también está funcionando). Sin embargo, una vez que redirijo, el usuario requerido no está definido. : ''(
La parte extraña es que se llama a pasaporte.deserializeUser con cada solicitud. Se está obteniendo con éxito el objeto del usuario, pero en algún lugar a lo largo del camino del middleware, no se está configurando req.user (o no se está configurando).
// on successful auth, goto "/"
app.get(''/'', function(req, res) {
// if the request has the user object, go to the user page
if (req.user) {
res.redirect("/user/" + req.user._id);
}
res.render("index");
}
app.get(''/user/:uid'', function(req, res) {
console.log(req.user) // undefined
}
¿Ha configurado el estado de la sesión para su aplicación? Necesitas algo como esto ...
app.use(session({ secret: ''anything'' }));
app.use(passport.initialize());
app.use(passport.session());
¿Has intentado insertar en la cookieParser tu clave secreta?
var passport = require(''passport'');
var expressSession = require(''express-session'');
app.use(express.static(path.join(__dirname, ''public'')));
app.use(cookieParser(''mySecretKey''));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(expressSession({
secret: ''mySecretKey'',
resave: false,
saveUninitialized: true
}));
app.use(passport.initialize());
app.use(passport.session());
Anteriormente tengo este código (no funcionó):
app.use(express.static(path.join(__dirname, ''public'')));
app.use(cookieParser(''abcdefg''));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(session({
secret: ''abcdefg'',
resave: true,
saveUninitialized: false,
cookie: { secure: true } // this line
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(require(''stylus'').middleware(path.join(__dirname, ''public'')));
Luego elimino la opción de cookie del inicializador de sesión:
app.use(express.static(path.join(__dirname, ''public'')));
app.use(cookieParser(''abcdefg''));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({extended: true}));
app.use(session({
secret: ''abcdefg'',
resave: true,
saveUninitialized: false
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(require(''stylus'').middleware(path.join(__dirname, ''public'')));
y ahora funciona.
Cuando use http request en el lado del cliente, recuerde adjuntar credenciales. En Angular2 necesitas agregar un argumento de opción: {withCredentials: true}. Después de esto, tendrá el mismo ID de sesión req. Hasta que lo restablezca nuevamente.
this._http.get("endpoint/something", { withCredentials: true })
El mío era sobre cookies y cors. Lo resolví agregando el siguiente código a mi servidor:
allowCrossDomain = function(req, res, next) {
res.header(''Access-Control-Allow-Origin'', ''http://localhost:3000''); // your website
res.header(''Access-Control-Allow-Credentials'', ''true'');
res.header(''Access-Control-Allow-Methods'', ''GET,PUT,POST,DELETE,OPTIONS'');
res.header(''Access-Control-Allow-Headers'', ''Content-Type, Authorization, Content-Length, X-Requested-With'');
if (''OPTIONS'' === req.method) {
res.send(200);
} else {
next();
}};
En las rutas, intente agregar: {session: true}
app.get(''/auto-login'', passport.authenticate(''cross'', {session: true}))
Me tropieza con el mismo problema porque simplemente copia y pega el código siguiente de la documentación de la sesión expresa, pero no lee completamente la documentación.
app.use(session({
secret: ''keyboard cat'',
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}))
En la documentación, mencionó:
Sin embargo, requiere un sitio web habilitado para https, es decir, HTTPS es necesario para las cookies seguras. Si se establece seguro y accede a su sitio a través de HTTP, la cookie no se configurará.
así que si solo tiene una conexión HTTP, elimine la opción segura, y el siguiente código debería funcionar:
app.use(session({
secret: ''keyboard cat'',
resave: false,
saveUninitialized: true,
//cookie: { secure: true } remove this line for HTTP connection
}))
Mi problema no era especificar el envío de cookies cuando usaba fetch en el lado del cliente. Funcionó después de incluir las credenciales: campo ''incluir'' en la solicitud.
fetch(''/api/foo'', {credentials: ''include''})
Sí, habilite sesiones como dice @Martin. Pero si está utilizando la versión Express 4. *, el middleware, como las sesiones, no están incluidas, por lo que deberá instalarlo individualmente.
- Agrega "express-session": "1.4.0" en tu paquete. Json
- NPM instalar
- usarlo
;
var express = require(''express'');
var cookieParser = require(''cookie-parser'')
var session = require(''express-session'')
var app = express()
app.use(cookieParser()) // required before session.
app.use(session({secret: ''keyboard cat''}))
Para más información, consulte la documentación de la sesión expresa.
Si su pila de middleware no está clara, suponiendo que tiene middleware de sesión en alguna parte , puede guardar la sesión antes de la redirección:
if (req.user) {
req.session.save(function (err) {
if (err) {
// ... panic!
}
res.redirect("/user/" + req.user._id);
});
return;
}
Soy súper nuevo en Node, pero fue un problema de middleware para mí. Se agregó bodyParser y se reordenó para solucionarlo.
Código roto:
app.use(express.cookieParser(''secret''));
app.use(express.cookieSession());
app.use(express.session({ secret: ''anything'' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(express.static(path.join(__dirname, ''public'')));
Código de trabajo:
app.use(express.static(path.join(__dirname, ''public'')));
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.session({ secret: ''anything'' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
Espero que esto ayude
Tenía exactamente el mismo problema. Para mí, la solución fue usar "sesiones de cliente" en lugar de "sesión expresa". ¿Probablemente mala configuración de sesiones?
Código que no funciona:
var session = require(''express-session'');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, ''public'')));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(session({
secret: ''random string'',
resave: true,
saveUninitialized: true,
cookie: { secure: true }
}));
Código de trabajo:
var session = require(''client-sessions'');
app.use(bodyParser.urlencoded({ extended: false }));
app.use(express.static(path.join(__dirname, ''public'')));
app.use(cookieParser());
app.use(bodyParser.json());
app.use(session({
cookieName: ''session'',
secret: ''random string'',
duration: 30 * 60 * 1000,
activeDuration: 5 * 60 * 1000,
}));
Tuve el mismo problema, tanto con req.isAuthenticated () como con req.user, así es como resolví
req.isAuthenticated () se resolvió reemplazando findOne () con find () en el método findById () dentro de deserialize (), luego pude guardar la solicitud autenticada, de lo contrario no devolvía nada.
req.user resuelto ajustando el orden, se debe almacenar la primera sesión express, se debe inicializar el pasaporte y luego la tienda de la próxima sesión en pasaporte.sesión () y luego podemos acceder a req.user, luego de guardar la sesión en pasaporte.sesión ()
app.use(session(...));
app.use(passport.initialize());
app.use(passport.session());
// Now we can access req.user so after we will call req.user, if we write it above these, it will always return underfined
app.use(function(req, res, next){
res.locals.user = req.user || null
next();
})
Consulte, si está accediendo a req.user después de passport.session()
, si no, agregue su ruta a continuación.
Tuve exactamente el mismo problema con Express 4 y después de probar prácticamente todo lo que pude encontrar en línea, finalmente logré que funcionara agregando ''cookie-session''.
var cookieSession = require(''cookie-session'');
app.use(cookieSession({
keys: [''key1'', ''key2'']
}));
Tuve un problema diferente, algo con funciones bcrpt-node y arrow.
Código que funciona:
userSchema.methods.generateHash = function (password) {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
userSchema.methods.isValidPassword = function (password) {
return bcrypt.compareSync(password, this.password);
};
Código que no funciona:
userSchema.methods.generateHash = (password) => {
return bcrypt.hashSync(password, bcrypt.genSaltSync(8), null);
};
userSchema.methods.isValidPassword = (password) => {
return bcrypt.compareSync(password, this.password);
};
Una vez que tenga la configuración de su sesión exprés, asegúrese de tener el pasaporte de serialización y deserialización, en la función de deserialización que es cuando se genera el usuario requerido. Vea la explicación here de otra pregunta de .
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});