Що робить проміжне програмне забезпечення passport.session ()?


125

Я будую систему аутентифікації за допомогою Passport.js за допомогою програми Easy Node Authentication: Setup and Local guide .

Я розгублений, що passport.session()робить.

Погравши з різним проміжним програмним забезпеченням, я зрозумів, що express.session()саме це посилає клієнтові ідентифікатор сеансу через файли cookie, але я розгублений, що passport.session()робить і чому це потрібно додатково express.session().

Ось як я налаштував свою заявку:

// Server.js налаштовує додаток та налаштовує веб-сервер

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

Відповіді:


139

passport.session() виконує функцію проміжного програмного забезпечення для зміни об'єкта req та зміни значення "користувача", яке є поточним ідентифікатором сеансу (від клієнтського файлу cookie), на справжній об'єкт деріаріалізованого користувача.

Хоча в інших відповідях є хороші моменти, я подумав, що можна надати ще якусь конкретну деталь.

app.use(passport.session());

еквівалентно

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

Де "сесія" посилається на таку стратегію, яка входить в комплект із паспортом JS.

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

Зокрема рядки 59-60:

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

Там, де він по суті діє як проміжне програмне забезпечення і змінює значення властивості 'user' в об'єкті req, щоб містити десеріалізовану ідентичність користувача. Щоб дозволити цьому правильно працювати, ви повинні включити serializeUserта deserializeUserфункціонувати у свій спеціальний код.

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

Це знайде правильного користувача з бази даних і передасть його як змінну закриття в зворотний виклик, done(err,user);тому вищевказаний код у passport.session()can може замінити значення 'user' в об'єкті req та перейти до наступного середнього програмного забезпечення в купі.


ей, як я можу зберігати дані користувачів лише в сеансі, я не хочу їх безпосередньо зберігати в базі даних
Newbiee

1
"у заголовках запиту"? не просто в об’єкт запиту
caub

Я помітив, що якщо стратегія сеансу здатна відновити аутентифікацію та десеріалізувати користувача. Але незважаючи на те, що автентифікація все ж переходить до наступної стратегії, яка є моїм сценарієм у Facebook. Цікаво, у чому сенс стратегії сеансу, якщо вона все ще продовжує звертатися до наступних стратегій, навіть коли сеанс зможе відновити користувача.
нішант

15

З документації

У програмі на основі Connect або Express для ініціалізації паспорта потрібно проміжне програмне забезпечення passport.initialize (). Якщо ваша програма використовує постійні сеанси входу, також слід використовувати проміжне програмне забезпечення passport.session ().

і

Сесії

У типовому веб-додатку облікові дані, що використовуються для автентифікації користувача, будуть передані лише під час запиту на вхід. Якщо аутентифікація пройде успішно, сеанс буде встановлений і підтримується за допомогою файлу cookie, встановленого в браузері користувача.

Кожен наступний запит не буде містити облікові дані, а скоріше унікальний файл cookie, який ідентифікує сеанс. Щоб підтримувати сеанси входу, Passport буде серіалізувати та дезаріалізувати екземпляри користувачів до сеансу та з нього.

і

Зауважте, що ввімкнення підтримки сеансу є абсолютно необов’язковим, хоча рекомендується для більшості програм. Якщо ввімкнено, обов'язково використовуйте express.session () перед passport.session (), щоб забезпечити відновлення сеансу входу в правильному порядку.


1
Дякую за швидку відповідь, але це не відповідає на моє запитання. Також зауважте, що якщо у вас є експрес-додаток та використання express.session (), будь-який клієнт, який підключається до вашого експрес-сервера (незалежно від того, він має автентифікацію чи ні), йому буде призначено сеанс за допомогою файлу cookie. Це не залежить від того, перебуває він на захищеній логіном сторінці вашої програми чи ні. Я все ще хотів би знати різницю між обома проміжними програмами.
Жорж Крінкер

1
@GeorgesKrinker - це методи serializeUser () та deserializeUser. Експрес-програмне забезпечення відновить інформацію про сеанс, але це не обов'язково пов'язано з тим, як паспорт керує інформацією про користувача. Це потрібно зробити після того, як сеанс буде зволожений експресом.
Джош К.

Я був під враженням, що методи serializeUser () та deserializeUser працювали на автентифікацію () в межах маршрутів.
Жорж Крінкер

@GeorgesKrinker Я так не думаю. Коли я користувався паспортом, я лише дзвонив .authenticate під час входу.
Джош К.

app.post('/login', passport.authenticate('local'), ...
Джош К.

11

Хоча ви будете використовувати PassportJsдля перевірки користувача як частину вашої URL-адреси для входу, вам все ще потрібен певний механізм, щоб зберігати цю інформацію користувача в сеансі та отримувати її з кожним наступним запитом (тобто серіалізувати / десеріалізувати користувача).

Тож фактично ви автентифікуєте користувача з кожним запитом, навіть незважаючи на те, що для цієї автентифікації не потрібно шукати базу даних чи дані, як у відповіді на вхід. Тож паспорт розглядає автентифікацію сеансу також як ще одну стратегію аутентифікації.

І щоб використовувати цю стратегію - яка названа session, просто використовуйте простий ярлик - app.use(passport.session()). Також зауважте, що саме ця стратегія бажає вам реалізувати функції серіалізації та десеріалізації з зрозумілих причин.


11

Він просто аутентифікує сеанс (який заповнений express.session()). Він еквівалентний:

passport.authenticate('session');

як видно з коду тут:

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


6
Що ви маєте на увазі? Він працює на кожному запиті і не обов'язково має будь-які дані для автентифікації. Ви не хотіли б дати мені трохи більше деталей щодо робочого процесу, який відбувається при кожному запиті?
Жорж Крінкер

6
Так, воно працює на кожному запиті. Ідентифікатор сеансу, що генерується Express, - це унікальний ідентифікатор, який приблизно еквівалентний маркеру аутентифікації, який браузер надсилає з кожним запитом. Дані, що зберігаються в цьому сеансі, використовуються для відновлення стану аутентифікації користувача.
Джаред Гансон,

Привіт @JaredHanson Не могли б ви поглянути на це . Я не міг знайти відповіді ніде?
Сарас Ар’я

@JaredHanson Я намагаюся використовувати passport.js для автентифікації з широко використовуваним сервером авторизації з відкритим кодом, який відповідає OAuth2. Але я отримую помилку. Чи готові ви допомогти вирішити проблему? Ось посилання: stackoverflow.com/questions/38176236 / ...
DollarCoffee

@JaredHanson: Що я зауважую, це те, що об'єкт req, доповнений інформацією passport.user, відразу після входу через google-oauth, втрачається, коли наступний запит на нову сторінку робиться на сайті. Це очікувана поведінка? Тоді я втрачаю, як повернути нещодавно ввійшли інформацію про користувача?
користувач1102171
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.