2013-11-13 2 views
102

У меня возникла проблема с модулем паспорта и экспресс-службой.Ошибка: не удалось сериализовать пользователя на сеанс

Это мой код, и я просто хочу использовать жестко зарегистрированный логин для первой попытки.

Я всегда получаю сообщение:

Я искал много и нашел некоторые посты в StackOverflow, но я не получил отказ.

Error: failed to serialize user into session at pass (c:\Development\private\aortmann\bootstrap_blog\node_modules\passport\lib\passport\index.js:275:19)

Мой код выглядит следующим образом.

'use strict'; 

var express = require('express'); 
var path = require('path'); 
var fs = require('fs'); 
var passport = require('passport'); 
var LocalStrategy = require('passport-local').Strategy; 
var nodemailer = require('nodemailer'); 

var app = express(); 

module.exports = function setupBlog(mailTransport, database){ 
var config = JSON.parse(fs.readFileSync('./blog.config')); 

app.set('view options', {layout: false}); 

app.use(express.static(path.join(__dirname, '../', 'resources', 'html'))); 


app.use(express.bodyParser()); 
app.use(express.cookieParser()); 
app.use(express.session({ secret: 'secret' })); 
app.use(passport.initialize()); 
app.use(passport.session()); 


app.get('/blog/:blogTitle', function(req, res) { 
    var blogTitle = req.params.blogTitle; 
    if(blogTitle === 'newest'){ 
    database.getLatestBlogPost(function(post) { 
     res.send(post); 
    }); 
    } else { 
    database.getBlogPostByTitle(blogTitle, function(blogPost) { 
     res.send(blogPost); 
    }); 
    } 
}); 

passport.use(new LocalStrategy(function(username, password, done) { 
    // database.login(username, password, done); 
    if (username === 'admin' && password === 'admin') { 
    console.log('in'); 
    done(null, { username: username }); 
    } else { 
    done(null, false); 
    } 
})); 

app.post('/login', passport.authenticate('local', { 
    successRedirect: '/accessed', 
    failureRedirect: '/access' 
})); 





app.listen(8080); 
console.log('Blog is running on port 8080'); 

}(); 

ответ

217

Похоже, что вы не выполнили passport.serializeUser и passport.deserializeUser. Попробуйте добавить это:

passport.serializeUser(function(user, done) { 
    done(null, user); 
}); 

passport.deserializeUser(function(user, done) { 
    done(null, user); 
}); 
+1

Работал для меня. Почему мне не нужно использовать часть «id» как написанную повсюду? – schlenger

+6

@schlenger это будет зависеть от того, как вы реализуете сериализацию. Иногда вы выполняете сериализацию по идентификатору пользователя, что означает, что функция 'serializeUser' хранит только идентификатор пользователя в сеансе, а' deserializeUser' использует этот идентификатор для извлечения пользовательских данных из базы данных (например). Это делается для того, чтобы хранилище сеансов не содержало фактические пользовательские данные. – robertklep

+2

@roberklep Спасибо за ваш ответ :) – schlenger

10

Похоже, вы пропустили часть passportjs установки, в частности эти два метода:

passport.serializeUser(function(user, done) { 
    done(null, user._id); 
    // if you use Model.id as your idAttribute maybe you'd want 
    // done(null, user.id); 
}); 

passport.deserializeUser(function(id, done) { 
    User.findById(id, function(err, user) { 
    done(err, user); 
    }); 
}); 

Я добавил немного о ._id против .id, но этот фрагмент является из Configure Section из документов, дайте это другому чтению и удачи :)

22

Если вы решили не использовать сеансы, вы можете установить сеанс на значение false

app.post('/login', passport.authenticate('local', { 
    successRedirect: '/accessed', 
    failureRedirect: '/access', 
    session: false 
})); 
0

Здесь работает, но все еще ленивый способ использовать сеансы и «сериализовать» значения.

var user_cache = {}; 

passport.serializeUser(function(user, next) { 
    let id = user._id; 
    user_cache[id] = user; 
    next(null, id); 
}); 

passport.deserializeUser(function(id, next) { 
    next(null, user_cache[id]); 
}); 

в случае, или странные ошибки просто спросите себя: «Должен ли я rlly установить„_id“в моем пользовательском объекте?» - в большинстве случаев вы этого не делаете. Поэтому используйте правильный атрибут в качестве ключа.

0

Использование Promise с serializeUser & deserializeUser:

passport.serializeUser((user, done) => { 
    done(null, user.id); 
}); 

passport.deserializeUser((id, done) => { 
    // console.log(`id: ${id}`); 
    User.findById(id) 
    .then((user) => { 
     done(null, user); 
    }) 
    .catch((error) => { 
     console.log(`Error: ${error}`); 
    }); 
}); 

Пожалуйста, смотрите мой github repo для полного примера кода, как решить эту проблему.

Смежные вопросы