Passport.js - Kesalahan: gagal membuat serialisasi pengguna menjadi sesi


179

Saya mendapat masalah dengan modul Passport.js dan Express.js.

Ini adalah kode saya dan saya hanya ingin menggunakan login dengan hardcode untuk percobaan pertama.

Saya selalu menerima pesan:

Saya mencari banyak dan menemukan beberapa posting di stackoverflow tetapi saya tidak mendapatkan kegagalan.

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

Kode saya terlihat seperti ini.

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

}();

Terima kasih.

Jawaban:


362

Sepertinya Anda tidak menerapkan passport.serializeUserdan passport.deserializeUser. Coba tambahkan ini:

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

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

2
Bekerja untukku. Mengapa saya tidak harus menggunakan bagian 'id' seperti yang ditulis di tempat lain?
schlenger

9
@schlenger akan tergantung pada bagaimana Anda menerapkan serialisasi. Terkadang Anda membuat serial berdasarkan id pengguna, yang berarti bahwa serializeUserfungsi menyimpan hanya id pengguna di sesi, dan deserializeUsermenggunakan id itu untuk mengambil data pengguna dari database (misalnya). Ini untuk mencegah penyimpanan sesi berisi data pengguna aktual itu sendiri.
robertklep

+1 @robertklep komentar. Saya selalu menghindari serialisasi informasi pengguna tetapi hanya id (untuk alasan bloat / perf secara pribadi).
electblake

2
@robertklep Saya tidak ingin menyimpannya di sesi. Saya menggunakan JWT. Apakah serializeUser / deserializeUser diperlukan? Saya ingin sesi tidak. Saya menggunakan JWT
Internial

@Internial tidak yakin jika Anda membutuhkannya, tetapi itu akan menjadi hal yang mudah untuk diuji.
robertklep

44

Jika Anda memutuskan untuk tidak menggunakan sesi, Anda dapat mengatur sesi menjadi false

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

Tapi itu tidak akan mematikan sesi pada semua titik akhir lainnya (di mana saya juga tidak ingin sesi apa pun)
jayarjo

17

Kedengarannya seperti Anda melewatkan bagian dari pengaturan paspor, khususnya dua metode ini:

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

Saya menambahkan sedikit tentang ._idvs. .idtetapi cuplikan ini dari Bagian Konfigurasi dokumen, berikan yang lain baca dan semoga berhasil :)


2

Di sini cara yang bekerja tetapi masih malas untuk menggunakan sesi dan masih "membuat serialisasi" nilai-nilai.

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

dalam kasus atau kesalahan aneh tanyakan pada diri sendiri: "Apakah saya hanya mengatur '_id' di objek pengguna saya?" - dalam kebanyakan kasus Anda tidak. Jadi gunakan atribut yang tepat sebagai kunci.


0

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

Silakan lihat repo github saya untuk contoh kode lengkap bagaimana mengatasi masalah ini.


-1

di passport.use ('local-login' ...) / atau / ('local-singup' ...)

jika err Anda harus mengembalikan "false" err {return done (null, req.flash ('megsign', 'Nama pengguna sudah ada #! #'));} true {return done (null, false, req.flash (' megsign ',' Nama pengguna sudah ada #! # '));}

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.