J'utilise pssportjs avec Express 2.x et un stockage de sessions. Après une connexion, je ne reçois req.User qu'une seule fois. Dès que je redirige à nouveau req.User est indéfini.
Voici ma config:
passport.serializeUser(function(user, done) {
done(null, user._id);
});
passport.deserializeUser(function(userId, done) {
User.findOne({_id: userId} ,function(err, user){
done(err, user);
});
});
// Authentication Strategy
passport.use(new FacebookStrategy({
clientID: CONFIG.fb.appId,
clientSecret: CONFIG.fb.appSecret,
callbackURL: CONFIG.fb.callbackURL
},
function(accessToken, refreshToken, profile, done) {
// asynchronous verification, for effect...
process.nextTick(function () {
User.findOne({ 'accounts.uid': profile.id, 'accounts.provider': 'facebook' }, function(err, olduser) {
if(olduser) {
done(null, olduser);
} else {
var newuser = new User();
var account = {provider: "facebook", uid: profile.id};
newuser.accounts.Push(account);
newuser.firstname = profile.name.givenName;
newuser.lastname = profile.name.familyName;
newuser.email = "TBD...";
newuser.save(function(err) {
if(err) { throw err; }
done(null, newuser);
});
}
});
});
}
));
var app = module.exports = express.createServer();
// configure express
app.configure(function(){
app.set('views', __dirname + '/views');
app.set('view engine', 'ejs');
app.use(express.compiler({ src : __dirname + '/public', enable: ['less']}));
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.methodOverride());
//app.use(express.session({ secret: "keyboard cat" }));
app.use(express.session({
secret: "victory cat",
store: new MongoStore({
url: CONFIG.dbMongo.url
})
}));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(express.static(__dirname + '/public'));
});
Ce sont mes itinéraires:
app.get('/auth/facebook', passport.authenticate('facebook', { scope: ['user_status', 'user_photos'] }));
app.get('/auth/facebook/callback', passport.authenticate('facebook', { successRedirect: '/index', failureRedirect: '/' }));
app.get('/index', function(req, res) {
res.render('index.ejs', {
siteTitle: "Welcome",
siteUrl: CONFIG.server.siteUrl,
user: req.user
});
});
Et enfin, voici comment j'essaie d'accéder à l'objet utilisateur de mon point de vue:
<div class="page-header">
<h3><%= siteTitle %></h3>
</div>
<% if (!user) { %>
<p>Not logged in !</p>
<% } else { %>
<p>Hello, <%= user.firstname %> <%= user.lastname %>.</p>
<% } %>
Après l'authentification avec facebook, mon affichage affiche correctement le prénom et le nom. Après une autre demande de page, req.User est indéfini (la désérialisation n'est pas appelée).
Qu'est-ce que je fais mal?
Utilisez des aides dynamiques. Voici un exemple d'objet user
à nu:
app.dynamicHelpers({
user: function(req, res){
var roles, name;
if (req.session && req.session.auth == true) {
roles = ['member'];
name = (req.session.user) ? req.session.user.name : 'Registered member';
id = (req.session.user) ? req.session.user.id : 0;
}
else {
roles = ['guest'];
name = 'Guest';
id = null;
}
return {
name: name,
id: id,
roles: roles,
isGuest: roles.indexOf('guest') !== -1,
isAdmin: roles.indexOf('admin') !== -1
}
}
});
Ensuite, à partir des vues, vous pouvez simplement utiliser #{user.name}
ou if user.isAdmin
etc., car l'objet user
est désormais accessible à d'autres parties de l'application.
Vous pouvez l'ajouter à app.js ou l'exiger à partir d'un fichier externe. Je garde tous mes aides dynamiques sous /utils/helpers.js
Avez-vous défini le middleware de passeport? À partir du document , vous devez faire
app.configure(function() {
app.use(express.cookieParser());
app.use(express.bodyParser());
app.use(express.session({ secret: 'keyboard cat' }));
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(express.static(YOUR_STATIC_DIR_PATH));
});
si vous utilisez Express 3.x ou Connect 2.x, définissez le secret des cookies au lieu du secret de la session
app.configure(function() {
app.use(express.cookieParser('keyboard cat'));
app.use(express.session());
app.use(express.bodyParser());
app.use(passport.initialize());
app.use(passport.session());
app.use(app.router);
app.use(express.static(YOUR_STATIC_DIR_PATH));
});
D'accord je l'ai eu:
L'erreur que j'ai commise n'était pas d'être dans le code que j'ai posté ci-dessus, ce qui est correct. J'avais un mauvais moyen de créer des liens vers des URL. J'ai donc forcé express à créer une nouvelle session chaque fois que j'ai utilisé l'un des liens rompus. Avec la nouvelle session, j'ai également perdu mon objet req.user.
Donc, si vous rencontrez des problèmes similaires, vérifiez également vos liens dans votre code HTML.
Merci à tous pour votre aide.
Vous pouvez transmettre les informations utilisateur à afficher dans le routeur:
res.render('user/dashboad', {
...
user: req.session.passport.user,
...