Passport.js - Lỗi: không thể tuần tự hóa người dùng thành phiên


179

Tôi gặp sự cố với mô-đun Passport.js và Express.js.

Đây là mã của tôi và tôi chỉ muốn sử dụng thông tin đăng nhập được mã hóa cứng cho lần thử đầu tiên.

Tôi luôn nhận được tin nhắn:

Tôi đã tìm kiếm rất nhiều và tìm thấy một số bài đăng trong stackoverflow nhưng tôi đã không nhận được thất bại.

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

Mã của tôi trông như thế này.

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

}();

Cảm ơn.

Câu trả lời:


362

Có vẻ như bạn đã không thực hiện passport.serializeUserpassport.deserializeUser. Hãy thử thêm điều này:

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

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

2
Đã làm cho tôi. Tại sao tôi không phải sử dụng phần 'id' như được viết ở mọi nơi khác?
schlenger

9
@schlenger nó sẽ phụ thuộc vào cách bạn thực hiện tuần tự hóa. Đôi khi bạn tuần tự hóa bởi id người dùng, điều đó có nghĩa là serializeUserhàm chỉ lưu trữ id người dùng trong phiên và deserializeUsersử dụng id đó để lấy dữ liệu người dùng từ cơ sở dữ liệu (ví dụ). Điều này là để ngăn lưu trữ phiên chứa dữ liệu người dùng thực tế.
robertklep

+1 bình luận @robertklep. Tôi luôn luôn tránh việc tuần tự hóa thông tin người dùng mà chỉ là id (vì lý do phình to / hoàn hảo cá nhân).
bầu chọn

2
@robertklep Tôi không muốn lưu trữ nó trong phiên. Tôi đang sử dụng JWT. Là serializeUser / deserializeUser cần thiết? Tôi muốn không có phiên. Tôi đang sử dụng JWT
Quốc tế

@ Nội bộ không chắc chắn nếu bạn cần chúng, nhưng nó sẽ là một điều dễ dàng để kiểm tra.
robertklep

44

Nếu bạn quyết định không sử dụng phiên, bạn có thể đặt phiên thành sai

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

Nhưng điều đó sẽ không tắt phiên trên tất cả các điểm cuối khác (nơi tôi cũng không muốn bất kỳ phiên nào)
jayarjo

17

Âm thanh như bạn đã bỏ lỡ một phần của thiết lập Passportjs, cụ thể là hai phương pháp sau:

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

Tôi đã thêm một chút về ._idso với .idnhưng đoạn trích này là từ Phần Cấu hình của tài liệu, hãy đọc thêm và chúc may mắn :)


2

Đây là một cách làm việc nhưng vẫn lười biếng để sử dụng các phiên và vẫn "tuần tự hóa" các giá trị.

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

trong trường hợp hoặc có lỗi lạ, hãy tự hỏi: "Tôi có nên đặt '_id' trong đối tượng người dùng của mình không?" - trong hầu hết các trường hợp bạn không. Vì vậy, sử dụng một thuộc tính thích hợp làm chìa khóa.


0

Sử dụng Promise với 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}`);
    });
});

Vui lòng xem repo github của tôi để biết ví dụ mã đầy đủ về cách giải quyết vấn đề này.


-1

trong Passport.use ('local-login' ...) / hoặc / ('local-singup' ...)

nếu có lỗi, bạn phải trả về "false" err {return xong (null, req.flash ('megsign', 'Tên người dùng đã tồn tại #! #'));} true {return xong (null, false, req.flash (' megsign ',' Tên người dùng đã tồn tại #! # '));}

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.