Ma question est semblable à celle-ci one , mais sa solution n’était pas claire.
J'utilise Passport pour utiliser Instagram. Une fois l’autorisation réussie, les utilisateurs sont dirigés vers "/". À ce stade, la demande a l'objet utilisateur (c'est-à-dire qu'il fonctionne). Cependant, une fois que je redirige, le req.user est indéfini. : '(
La partie étrange est que passport.deserializeUser est appelé à chaque demande. L'objet utilisateur a bien été récupéré, mais quelque part sur la route du middleware, req.user n'est pas défini (ou n'est pas défini).
// 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
}
Avez-vous configuré l'état de session pour votre application? Vous avez besoin de quelque chose comme ça ...
app.use(session({ secret: 'anything' }));
app.use(passport.initialize());
app.use(passport.session());
Mon problème ne spécifiait pas d'envoyer des cookies lors de l'utilisation de l'extraction côté client. Cela a fonctionné après avoir inclus les informations d'identification: champ 'include' dans la demande.
fetch('/api/foo', {credentials: 'include'})
Je suis super nouveau pour Node mais c'était un problème de middleware pour moi. BodyParser ajouté et réarrangé pour corriger.
Code cassé:
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')));
Code de travail:
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);
J'espère que cela t'aides
Auparavant, j'ai ce code (n'a pas fonctionné):
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')));
Ensuite, je supprime l'option cookie de l'initialiseur de session:
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')));
et maintenant ça marche.
Ouais, permets des sessions comme le dit @Martin. Toutefois, si vous utilisez la version Express 4. *, les middleware de type session ne sont pas fournis, vous devez donc l’installer individuellement.
;
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'}))
Pour plus d'informations, consultez la documentation de la session express.
Je rencontre le même problème à cause d'un simple copier-coller du code suivant dans la documentation de session express, mais je ne l'ai pas entièrement lu.
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
cookie: { secure: true }
}))
Dans la documentation, il est mentionné:
Cependant, il nécessite un site Web compatible https, c’est-à-dire que HTTPS est nécessaire pour les cookies sécurisés. Si sécurisé est activé et que vous accédez à votre fichier site via HTTP, le cookie ne sera pas défini.
donc, si vous avez juste une connexion HTTP, supprimez l'option sécurisée, et le code ci-dessous devrait fonctionner:
app.use(session({
secret: 'keyboard cat',
resave: false,
saveUninitialized: true,
//cookie: { secure: true } remove this line for HTTP connection
}))
Dans les itinéraires, essayez d'ajouter: {session: true}
app.get('/auto-login', passport.authenticate('cross', {session: true}))
J'ai eu exactement le même problème avec Express 4 et après avoir essayé à peu près tout ce que je pouvais trouver en ligne, j'ai finalement réussi à le faire fonctionner en ajoutant «cookie-session».
var cookieSession = require('cookie-session');
app.use(cookieSession({
keys: ['key1', 'key2']
}));
La mienne concernait les cookies et les cors. J'ai résolu en ajoutant le code suivant sur mon serveur:
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();
}};
Lorsque vous utilisez une requête http côté client, n'oubliez pas de joindre les informations d'identification . Dans Angular2, vous devez ajouter un argument d'option: {withCredentials: true}. Après cela, vous aurez le même req.sessionID jusqu'à ce que vous le réinitialisiez.
this._http.get("endpoint/something", { withCredentials: true })
Une fois que vous avez configuré votre session express, assurez-vous que votre passeport est sérialisé et désérialisé, dans la fonction de désérialisation, à la génération de req.user. Voir l'explication ici d'une autre question de stackoverflow.
passport.serializeUser(function(user, done) {
done(null, user);
});
passport.deserializeUser(function(user, done) {
done(null, user);
});
Si votre pile de middleware n'est pas claire, en supposant que vous disposiez d'un middleware de session quelque part , vous pouvez enregistrer la session avant la redirection:
if (req.user) {
req.session.save(function (err) {
if (err) {
// ... panic!
}
res.redirect("/user/" + req.user._id);
});
return;
}
Mes deux cents: Code ne fonctionne pas:
server.use(
session({
secret: "secretsssss",
rolling: false,
resave: false,
saveUninitialized: false,
cookie: {
sameSite: true, //this line
maxAge: 60 * 60 * 1000
}
})
);
code de travail:
server.use(
session({
secret: "secretsssss",
rolling: false,
resave: false,
saveUninitialized: false,
cookie: {
sameSite: false, // i think this is default to false
maxAge: 60 * 60 * 1000
}
})
);
En faisant passport.authenticate
, vous pouvez ajouter session: true
pour résoudre votre problème:
app.post("/login", passport.authenticate('local', {
'failureRedirect': '/login',
'session': true
}), (req, res)=>{ res.redirect("/"); });
Le serveur envoie l'en-tête SetCookie, puis le descripteur de navigateur pour le stocker, puis le cookie est envoyé avec les demandes adressées au même serveur à l'intérieur d'un en-tête HTTP Cookie.
Je devais définir withCredentials: true dans mon client. (axios.js)
const config = {
withCredentials: true,
headers: {
'Content-Type': 'application/json',
},
};
axios.put(url, { page: '123' }, config)
.then(res => console.log('axios', res))
.catch(err => console.log('axios', err));
Ensuite, des problèmes de CORS surviennent.
J'ai donc ajouté ceci à mon serveur express:
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Origin', req.headers.Origin);
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE');
res.header('Access-Control-Allow-Headers', 'X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept');
if ('OPTIONS' == req.method) {
res.send(200);
} else {
next();
}
});
Lorsque vous authentifiez un utilisateur, la valeur de la requête req.user
est renseignée. Pour savoir si l'identifiant est l'utilisateur et remplissez cette valeur, un cookie est utilisé. Si, comme moi, vous configurez la session avec des cookies sécurisés, ceux-ci ne seront disponibles que sur HTTPS
, ce qui n'est pas la configuration standard d'un serveur de développement local, par exemple. Pour que les cookies fonctionnent sur HTTP
, commentez cookie: { secure: true }
et la valeur req.user
sera correctement configurée:
this.app.use(session({
resave: true,
saveUninitialized: true,
secret: process.env.SESSION_SECRET || "a secret",
// cookie: { secure: true },
}));
Si, raisonnablement, vous souhaitez utiliser des cookies supérieurs à HTTPS
uniquement en production, vous pouvez procéder de la manière suivante:
cookie: { secure: process.env.ENV === 'PRODUCTION' }
Le mien était différent de tout cela. Auparavant, je développais un site Wordpress sur localhost, puis je passais à un projet distinct Node/React.
Le cookie du site Wordpress était toujours présent et envoyé depuis que les deux projets ont été exécutés sur localhost. Cela causait le problème.
J'ai dû effacer les cookies pour localhost et ensuite cela a fonctionné.
J'ai eu le même problème, à la fois avec req.isAuthenticated () et req.user, voici comment j'ai résolu
req.isAuthenticated () résolu en remplaçant findOne () par find () dans la méthode findById () à l'intérieur de deserialize (), je pourrais alors sauvegarder un req authentifié, sinon il ne renverrait rien.
req.user résolu en ajustant l'ordre, la première session express doit être stockée, puis le passeport doit être initialisé, puis la session suivante stockée dans passport.session (), après quoi nous pouvons accéder à req.user ()
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();
})
Voir, si vous accédez à req.user après passport.session()
, sinon ajoutez votre route ci-dessous.
Avez-vous essayé d'insérer votre clé secrète dans le cookieParser?
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());
Avait exactement le même problème. Pour moi, la solution consistait à utiliser "sessions client" au lieu de "session express". Probablement une mauvaise configuration de session?
Code non fonctionnel:
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 }
}));
Code de travail:
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,
}));