2013-03-11 3 views
10

Я использую только паспорт.js для входа в Google, Facebook и Twitter.Passport.js, не связанный с сериализацией пользователя

Node.js v0.8.19 с express.js 3.1.0 и версия паспортной версии 0.1.16. (паспорт-facebook - 0.1.5, твиттер - 0.1.4 паспорт-goolge-oauth - 0.1.5)

Все работает нормально какое-то время, через час или около того приложения, выполняющего паспорт.js прекращает сериализацию пользователя в сеансе req.user.

Facebook и Google получают смысл полных данных из соответствующего API,

passport.use(new FacebookStrategy({ 
    clientID: FACEBOOK_APP_ID, 
    clientSecret: FACEBOOK_APP_SECRET, 
    callbackURL: "http://localhost:3000/auth/facebook/callback" 
    }, 
    function(accessToken, refreshToken, profile, done) { 
     var temp = {} 
     temp.name = profile.displayName 
     temp.id = profile.id 
     console.log(temp) 
     return done(null, temp); 
})); 

The console.log здесь будут успешно печатать идентификатор пользователя и имя, однако после вызова

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

passport.deserializeUser(function(obj, done) { 
    done(null, obj); 
}); 

сериализации и десериализаций являются взято из паспорта-facebook example.

Пользователь не будет прикреплен к req.user.

Twitter никогда не получает, что далеко, после возвращения в обратном вызове URL, твиттер дает ошибку:

Error: failed to find request token in session 
[03/11 23:28:24 GMT]  at Strategy.OAuthStrategy.authenticate    

Примечание: эти неудачи случаются только после определенного периода времени, работы должным образом на некоторое время. Вот почему я думаю, что это может быть проблема с памятью, например Im, сохраняющая сессию в памяти вместо cooke.

Это моя экспресс конфигурация

app.configure(function(){ 
    app.set('port', process.env.PORT || 8080); 
    app.set('views', __dirname + '/views'); 
    app.set('view engine', 'jade'); 
    app.use(express.favicon()); 
    app.use(express.logger('dev')); 
    app.use(express.cookieParser()); 
    app.use(express.bodyParser()); 
    app.use(express.methodOverride()); 
    app.use(express.cookieSession({ secret: 'tobo!', cookie: { maxAge: new Date(Date.now() +  3600000), }})); 
    app.use(passport.initialize()); 
    app.use(passport.session()); 
    app.use(app.router); 
    app.use(express.static(__dirname + '/public')); 
}); 

приложение, которое я посмотрел на список рассылки и т.д., но я не мог найти что-то соответствие этой проблемы. Я проверил мой локальный хост и на сервере nodejitsu. Все работает некоторое время, а затем терпит неудачу.

+3

Ни паспорт.serializeUser(), ни deserializeUser() выглядят так, как будто они когда-либо могли работать. serializeUser() должен взять объект и сериализовать его в строку, которая может использоваться в cookie для однозначной идентификации пользователя. Обычно это делается путем вызова 'done (null, user.id)'. deserializeUser должен принимать одинаковый идентификатор (из файла cookie) и находить правильный набор данных в базе данных. С mongodb вы можете сделать 'User.findById (id, function (err, user) {done (err, user);});' –

+0

Значит, они должны быть строками? –

+0

[Здесь] (https://github.com/jaredhanson/passport-facebook/blob/master/examples/login/app.js) в примере с паспорт-facebook у них одинаковый сериализатор и десериализация, как и я. –

ответ

6

Я до сих пор не понимаю, почему возникла проблема, но я решил это, выполнив следующее.

Изменение

app.use(express.cookieSession({ secret: 'tobo!', cookie: { maxAge: new Date(Date.now() +  3600000), }})); 

в

app.use(express.cookieSession({ secret: 'tobo!', maxAge: 360*5 })); 

Я думаю, что сериализации весь пользовательский объект должен работать, так как deserializeUser просто передать обратно переданную печенье. Но не сериализуя весь пользовательский объект, он работает.

passport.serializeUser(function(user, done) { 
    console.log('serializeUser: ' + user._id) 
    done(null, user._id); 
}); 

passport.deserializeUser(function(id, done) { 
    db.users.findById(id, function(err, user){ 
     console.log(user) 
     if(!err) done(null, user); 
     else done(err, null) 
    }) 
}); 

Я имел ноль проблемы, так как я сделал это.

+1

Не уверен, что это на самом деле проблема, но я думаю, что 'maxAge' в файле cookie должно быть числом секунд, в течение которого файл cookie должен длиться, а не фактическое время его истечения (это то, что вы там положили) , – Will

25

Сначала вы должны понимать, для чего предназначены сериализация и десериализация.

1) serializeUser возьмите объект пользователя и сохраните любую информацию, которую вы хотите в сеансе, когда вы вернетесь done(null, user), в соответствии с вашим первым вопросом.

2) deserializeUser принимать информацию, хранящуюся в сессии (посланного cookieSession в каждом запросе) и проверяет, если сессия еще действительна для пользователя, и if(!err) done(null,user) верно, держит пользователя в сессии, где else done(err,null) удаляет его от сеанса, перенаправляя вас на то, что ваш app.get('/auth/:provider/callback') отправляет пользователя после проверки того, завершен ли сеанс или нет. Это должно прояснить ситуацию для вашего второго вопроса.

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