Phần mềm trung gian passport.session () làm gì?


125

Tôi đang xây dựng hệ thống xác thực bằng Passport.js bằng Xác thực nút dễ dàng: Hướng dẫn thiết lập và cục bộ .

Tôi bối rối về điều gì passport.session() hiện.

Sau khi thử nghiệm với các phần mềm trung gian khác nhau, tôi đã hiểu rằng đó express.session()là thứ gửi ID phiên qua cookie cho khách hàng, nhưng tôi bối rối về điều gì passport.session()làm được và tại sao nó lại được yêu cầu ngoàiexpress.session() .

Đây là cách tôi thiết lập ứng dụng của mình:

// Server.js định cấu hình ứng dụng và thiết lập máy chủ web

//importing our modules
var express = require('express');
var app = express();
var port = process.env.PORT || 8080;
var mongoose = require('mongoose');
var passport = require('passport');
var flash = require('connect-flash');

var configDB = require('./config/database.js');

//Configuration of Databse and App

mongoose.connect(configDB.url); //connect to our database

require('./config/passport')(passport); //pass passport for configuration

app.configure(function() {

    //set up our express application

    app.use(express.logger('dev')); //log every request to the console
    app.use(express.cookieParser()); //read cookies (needed for auth)
    app.use(express.bodyParser()); //get info from html forms

    app.set('view engine', 'ejs'); //set up ejs for templating

    //configuration for passport
    app.use(express.session({ secret: 'olhosvermelhoseasenhaclassica', maxAge:null })); //session secret
    app.use(passport.initialize());
    app.use(passport.session()); //persistent login session
    app.use(flash()); //use connect-flash for flash messages stored in session

});

//Set up routes
require('./app/routes.js')(app, passport);

//launch
app.listen(port);
console.log("Server listening on port" + port);

Câu trả lời:


139

passport.session() hoạt động như một phần mềm trung gian để thay đổi đối tượng req và thay đổi giá trị 'người dùng' hiện là id phiên (từ cookie của ứng dụng khách) thành đối tượng người dùng được mô tả thực sự.

Trong khi các câu trả lời khác tạo ra một số điểm tốt, tôi nghĩ rằng một số chi tiết cụ thể hơn có thể được cung cấp.

app.use(passport.session());

tương đương với

app.use(passport.authenticate('session'));

Trong đó 'phiên' đề cập đến chiến lược sau đi kèm với passportJS.

https://github.com/jaredhanson/passport/blob/master/lib/strategies/session.js

Cụ thể các dòng 59-60:

var property = req._passport.instance._userProperty || 'user';
req[property] = user;

Nơi nó về cơ bản hoạt động như một phần mềm trung gian và thay đổi giá trị của thuộc tính 'người dùng' trong đối tượng req để chứa danh tính đã được deserialized của người dùng. Để cho phép điều này hoạt động chính xác, bạn phải bao gồm serializeUservà các deserializeUserchức năng trong mã tùy chỉnh của mình.

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

passport.deserializeUser(function (user, done) {
    //If using Mongoose with MongoDB; if other you will need JS specific to that schema.
    User.findById(user.id, function (err, user) {
        done(err, user);
    });
});

Thao tác này sẽ tìm đúng người dùng từ cơ sở dữ liệu và chuyển nó dưới dạng biến đóng vào lệnh gọi lại done(err,user);để đoạn mã trên trong passport.session()có thể thay thế giá trị 'người dùng' trong đối tượng req và chuyển cho phần mềm trung gian tiếp theo trong đống.


hey, làm thế nào tôi có thể lưu trữ thông tin chi tiết người dùng trong phiên duy nhất tôi không muốn lưu trữ chúng trong cơ sở dữ liệu dirctly
Newbiee

1
"trong tiêu đề yêu cầu"? không chỉ trong yêu cầu đối tượng
caub

Tôi đã nhận thấy rằng nếu chiến lược phiên có thể khôi phục xác thực và giải mã hóa người dùng. Nhưng mặc dù vậy, xác thực vẫn chuyển sang chiến lược tiếp theo, đó là xác thực facebook trong kịch bản của tôi. Tôi tự hỏi mục đích của chiến lược phiên là gì nếu nó vẫn tiếp tục gọi các chiến lược sau ngay cả khi phiên có thể khôi phục người dùng.
nishant

15

Từ tài liệu

Trong ứng dụng dựa trên Connect hoặc Express, cần có phần mềm trung gian passport.initialize () để khởi tạo Passport. Nếu ứng dụng của bạn sử dụng các phiên đăng nhập liên tục, thì phần mềm trung gian passport.session () cũng phải được sử dụng.

Phiên

Trong một ứng dụng web điển hình, thông tin đăng nhập được sử dụng để xác thực người dùng sẽ chỉ được truyền trong khi yêu cầu đăng nhập. Nếu xác thực thành công, một phiên sẽ được thiết lập và duy trì thông qua tập hợp cookie trong trình duyệt của người dùng.

Mỗi yêu cầu tiếp theo sẽ không chứa thông tin xác thực, mà là cookie duy nhất xác định phiên. Để hỗ trợ các phiên đăng nhập, Passport sẽ tuần tự hóa và giải mã hóa các phiên bản người dùng đến và đi từ phiên này.

Lưu ý rằng việc bật hỗ trợ phiên là hoàn toàn tùy chọn, mặc dù nó được khuyến nghị cho hầu hết các ứng dụng. Nếu được bật, hãy đảm bảo sử dụng express.session () trước passport.session () để đảm bảo rằng phiên đăng nhập được khôi phục theo đúng thứ tự.


1
Cảm ơn bạn đã trả lời nhanh chóng nhưng điều đó không trả lời câu hỏi của tôi. Ngoài ra, hãy lưu ý rằng nếu bạn có ứng dụng express và sử dụng express.session (), trên bất kỳ ứng dụng khách nào kết nối với máy chủ express của bạn (cho dù ứng dụng đó có được xác thực hay không), người đó sẽ được cung cấp một phiên thông qua cookie. Điều đó không phụ thuộc vào việc anh ta có ở trong trang được bảo vệ bằng đăng nhập của ứng dụng của bạn hay không. Tôi vẫn muốn biết sự khác biệt giữa cả hai phần mềm trung gian.
Georges Krinker

1
@GeorgesKrinker là phương thức serializeUser () và deserializeUser. Phần mềm trung gian nhanh sẽ khôi phục thông tin phiên, nhưng điều đó không nhất thiết phải liên quan đến cách hộ chiếu quản lý thông tin người dùng. Điều đó phải được thực hiện sau khi phiên được bù nước bằng cấp tốc.
Josh C.

Tôi có ấn tượng rằng các phương thức serializeUser () và deserializeUser chạy trên authenticate () trong các tuyến đường.
Georges Krinker

@GeorgesKrinker Tôi không nghĩ vậy. Khi tôi sử dụng hộ chiếu, tôi chỉ gọi .authenticate khi đăng nhập.
Josh C.

app.post('/login', passport.authenticate('local'), ...
Josh C.

11

Trong khi bạn sẽ sử dụng PassportJs để xác thực người dùng như một phần của URL đăng nhập của mình, bạn vẫn cần một số cơ chế để lưu trữ thông tin người dùng này trong phiên và truy xuất thông tin đó với mọi yêu cầu tiếp theo (tức là tuần tự hóa / giải mã hóa người dùng).

Vì vậy, trên thực tế, bạn đang xác thực người dùng với mọi yêu cầu, mặc dù xác thực này không cần tra cứu cơ sở dữ liệu hoặc oauth như trong phản hồi đăng nhập. Vì vậy, hộ chiếu sẽ coi xác thực phiên cũng như một chiến lược xác thực khác.

Và để sử dụng chiến lược này - được đặt tên session, chỉ cần sử dụng một phím tắt đơn giản - app.use(passport.session()). Cũng lưu ý rằng chiến lược cụ thể này sẽ muốn bạn triển khai các chức năng tuần tự hóa và giải mã hóa vì những lý do rõ ràng.


11

Nó chỉ đơn giản là xác thực phiên (được điền bởi express.session()). Nó tương đương với:

passport.authenticate('session');

như có thể thấy trong mã ở đây:

https://github.com/jaredhanson/passport/blob/42ff63c/lib/authenticator.js#L233


6
Ý anh là gì? Nó chạy theo mọi yêu cầu và không nhất thiết phải có bất kỳ thông tin đăng nhập nào để xác thực. Bạn có phiền cho tôi biết thêm một chút chi tiết về quy trình làm việc theo từng yêu cầu không?
Georges Krinker

6
Có, nó chạy theo mọi yêu cầu. ID phiên được tạo bởi Express, là một ID duy nhất gần tương đương với mã thông báo xác thực mà trình duyệt gửi đi với mọi yêu cầu. Dữ liệu được lưu trữ trong phiên này được sử dụng để khôi phục trạng thái xác thực của người dùng.
Jared Hanson

Xin chào @JaredHanson bạn có thể có một cái nhìn tại này . Tôi không thể tìm thấy câu trả lời ở bất cứ đâu?
Saras Arya

@JaredHanson Tôi đang cố gắng sử dụng passport.js để xác thực với một máy chủ ủy quyền nguồn mở được sử dụng rộng rãi tuân thủ OAuth2. Nhưng tôi đang nhận được một lỗi. Bạn có sẵn sàng giúp giải quyết vấn đề? Đây là liên kết: stackoverflow.com/questions/38176236/…
DollarCoffee

@JaredHanson: Những gì tôi quan sát được là đối tượng req được tăng cường với thông tin passport.user ngay sau khi đăng nhập qua google-oauth, bị mất khi yêu cầu tiếp theo cho một trang mới được thực hiện trên trang web. Đây có phải là hành vi được mong đợi không? Sau đó, tôi không biết làm thế nào để lấy lại thông tin người dùng đã đăng nhập gần đây?
user1102171
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.