Passport.js - Hata: Kullanıcı oturumu seri hale getiremedi


180

Passport.js modülü ve Express.js ile ilgili bir sorunum var.

Bu benim kodum ve sadece ilk denemek için sabit kodlu bir giriş kullanmak istiyorum.

Her zaman mesajı alıyorum:

Çok aradım ve stackoverflow bazı mesajlar buldum ama başarısızlık alamadım.

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

Kodum böyle görünüyor.

'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');

}();

Teşekkürler.

Yanıtlar:


363

Görünüşe göre uygulama yapmadın passport.serializeUserve passport.deserializeUser. Bunu eklemeyi deneyin:

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

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

2
Benim için çalıştı. Neden 'id' kısmını başka hiçbir yerde yazıldığı gibi kullanmak zorunda değilim?
schlenger

9
@schlenger, serileştirmeyi nasıl uyguladığınıza bağlı olacaktır. Bazen kullanıcı kimliğine göre serileştirirsiniz, yani serializeUserişlev oturumda yalnızca kullanıcı kimliğini depolar ve kullanıcı kimliğini deserializeUserbir veritabanından (örneğin) almak için bu kimliği kullanır. Bu, oturum depolamasının gerçek kullanıcı verilerini içermesini önlemektir.
robertklep

+1 @robertklep yorumu. Ben her zaman kullanıcı bilgilerini serileştirmekten kaçınırdım ama sadece kimlikleri (kişisel olarak şişkinlik / mükemmel nedenlerle).
Electblake

2
@robertklep Oturumda saklamak istemiyorum. JWT kullanıyorum. SerializeUser / deserializeUser gerekli mi? Oturum yok istiyorum. JWT kullanıyorum
Internial

@Internial onlara ihtiyacınız olup olmadığından emin değil, ama test etmek kolay bir şey olurdu.
robertklep

44

Oturumları kullanmamaya karar verirseniz, oturumu false olarak ayarlayabilirsiniz

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

Ama bu diğer tüm uç noktalarda oturumu kapatmayacak (burada da herhangi bir oturum istemiyorum)
jayarjo

17

Passportjs kurulumunun bir bölümünü, özellikle de bu iki yöntemi kaçırdığınız anlaşılıyor:

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);
  });
});

Ben yaklaşık biraz eklenen ._idvs. .idama bu pasajı dan Yapılandırma Bölüm vermek, dokümanlar başka okuma ve iyi şanslar :)


2

Burada oturumları kullanmak ve hala değerleri "serileştirmek" için çalışan ama yine de tembel bir yol.

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]);
});

veya garip hataların olması durumunda kendinize şu soruyu sorun: "Kullanıcı nesnemde '_id' ayarını rlly olarak ayarlayabilir miyim?" - çoğu durumda yapmazsınız. Bu yüzden anahtar olarak uygun bir özellik kullanın.


0

Promise'i serializeUser & deserializeUser ile kullanma:

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}`);
    });
});

Bu sorunun nasıl çözüleceğine ilişkin tam kod örneği için lütfen github repo'ma bakın .


-1

passport.use ('local-login' ...) / veya / ('local-singup' ...) içinde

err "false" döndürmeniz gerekir err {return done (null, req.flash ('megsign', 'Kullanıcı adı zaten var!! #'));} true {return done (null, false, req.flash (' megsign ',' Kullanıcı adı zaten var!! # '));}

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.