Что заставляет Express-Session принять решение начать новый сеанс? - PullRequest
0 голосов
/ 05 мая 2019

У меня проблема с тем, что одно место в моем коде (часть аутентификации) помещает что-то в сеанс, а другое место в коде пытается получить к нему доступ (моя часть GraphQL API). Проблема в том, что когда вторая часть пытается получить данные, их там нет.

Когда я регистрирую request.session.id, я ясно вижу основную проблему: между двумя запросами меняется сам сеанс. Запрос авторизации происходит и помещает данные в сеанс A, но когда код GraphQL обращается к request.session, он получает сеанс B без данных.

Однако это не запрос «пожалуйста, отладьте мой код для меня». Вместо этого я просто хотел бы понять, как работает библиотека, чтобы я мог отлаживать себя.

Может ли кто-нибудь объяснить, как / почему express-session решает (предположительно, при получении нового запроса), что он должен отказаться от старого сеанса и начать новый? Из того, что я прочитал, скорее всего, это как-то связано с настройками моего домена, но я попытался поиграть с ними безуспешно, и на самом деле я просто хочу понять, как работает библиотека, особенно с точки зрения принятия решения о повторном использовании сеанс или создать новый.

1 Ответ

2 голосов
/ 07 мая 2019

@ machineghost, что за отличный вопрос!Существует большая путаница в отношении того, что делает модуль express-session и как его настроить.Я сделаю все возможное, чтобы объяснить.

Я думаю, что путаница вокруг express-sesion возникает из-за того, что модуль просто склеивает различные аспекты веб-сервера в одном месте, то есть req.session, для промежуточного программного обеспечения., маршруты и, возможно, (с помощью) веб-сокет-соединения для хранения и доступа к эфемерным данным о «пользователе» (сеанс чтения), который делает запрос.

Три аспекта, которые модуль пытается склеить, - это httpфайлы cookie, кратковременное хранилище данных и объект javascript req, который передается через промежуточное ПО и маршруты.Чтобы пролить свет на то, как это работает, подумайте о «обычном» HTTP-запросе, который был дан приложению Express, использующему модуль express-session (ES для краткости):

  • Express передаетзапрос к ES.
  • ES ищет файл cookie, который был установлен ранее.Это место, где возникает большинство зарегистрированных ошибок.ES требует, чтобы у вашего приложения был доступ к файлам cookie.Неправильная конфигурация обратных прокси-серверов, CORS или Fetch API потенциально может помешать ES получить доступ к cookie, который он пытается установить в ответах HTTP.Если каждый, кто сталкивался с ошибкой в ​​ES, открыл отладчик, установил точку останова в записи для промежуточного программного обеспечения ES и искал наличие файла cookie connect.id.У ES было бы гораздо меньше проблем, IMO.ПРИМЕЧАНИЕ: вы можете обойти требование к cookie-файлам, но в лучшем случае оно хакерское.
  • Если ES обнаружил cookie-файл, он использует это значение для поиска сеанса во всех приложениях, настроенных в параметре store.Это может быть Redis или MongoDB, или, если вы не указали, он просто находится в памяти в процессе узла.
  • Если ES либо не обнаружил cookie, либо поиск не возвратил сеанс, он создаст свойство для req объекта с именем session, который является просто пустым объектом, то есть {}.Промежуточное программное обеспечение или маршруты, расположенные ниже по линии, будут иметь доступ к этому.
  • ES устанавливает cookie для объекта res как способ для будущих запросов присоединить сеанс, как описано выше.
  • ES оборачивает метод req.end функцией, которая проверяет, следует ли сохранить объект req.session.Такие параметры, как resave и saveUninitialized будут определять, сохраняет ли ES сеанс для данного запроса.ПРИМЕЧАНИЕ. В случае перенаправления HTTP, например 302, метод res.end не вызывается до тех пор, пока не будет сделан вновь перенаправленный запрос.Это означает, что данные сеанса, которые установлены до перенаправления, недоступны для перенаправленного запроса.Это известно, и обходной путь заключается в явном сохранении сеанса перед перенаправлением с помощью req.session.save

Примечание о веб-сокетах

Для того, чтобы заставить веб-сокеты работать с ES, на базовом уровнеУровень, вы должны взять сеанс, который присоединен к запросу на изменение протоколов и подключить его к сокету для этого пользователя.Я написал простую библиотеку в качестве примера здесь .Примечание: этому 5 лет, и он был создан скорее как предмет для обсуждения, чем что-либо еще, но если вы посмотрите, как это работает, вы поймете идею.

Надеюсь, все это поможет, спасибо за публикацию!

...