Why is passport.deserializeUser called after req.user has been restored?

橙三吉。 提交于 2021-02-11 16:38:44

问题


According to the Passport Documentation on Sessions

...only the user ID is serialized to the session, keeping the amount of data stored within the session small. When subsequent requests are received, this ID is used to find the user, which will be restored to req.user.

However my test SPA which is based on Passport form-based authentication sample with debug messages added indicates req.user has already been restored before the app.get route handler is triggered.

Here is the output from an HTTP POST where the username and passport fields are empty -

[nodemon] starting `node app.js`
agenda-spa app listening at http://localhost:3000
handling request for:  / POST
handling request for:  / GET
xxx get root
xxx req.user  undefined
handling request for:  /style.css GET

req.user is undefined as expected

Here is the output from an HTTP POST with an authenticated username and password

handling request for:  / POST
xxx passport.use  sss
xxx findByUsername sss
xxx password match
xxx serializeUser { id: 1, username: 'sss', password: 'sss' }
xxx auth success
xxx deserializeUser 1
xxx findById 1
handling request for:  / GET
xxx get root
xxx req.user  { id: 1, username: 'sss', password: 'sss' }
xxx deserializeUser 1
xxx findById 1
handling request for:  /style.css GET

I would expect it to be -

...
xxx deserializeUser 1
xxx findById 1
xxx req.user  { id: 1, username: 'sss', password: 'sss' }
...

Why is passport.deserializeUser called after req.user has been restored?


回答1:


First, in my case I get:

xxx passport.use  sss
xxx findByUsername sss
xxx password match
xxx serializeUser { id: 1, username: 'sss', password: 'sss' }
xxx auth success
xxx deserializeUser 1
xxx findById 1
handling request for:  / GET
xxx get root
xxx req.user  { id: 1, username: 'sss', password: 'sss' }

To reproduce the issue I run the following script:

#!/usr/bin/env bash
set -eu
rm cookies.txt || true
args=(
-sSv -b cookies.txt -c cookies.txt
)
curl "${args[@]}" -d 'username=sss&password=sss' localhost:3000
curl "${args[@]}" localhost:3000

Let's add some debugging information to understand where requests start:

$ DEBUG=* node app.js
...
  express:router dispatching POST / +10s
  express:router session  : / +1ms
  express-session no SID sent, generating session +1ms
  express:router initialize  : / +3ms
  express:router authenticate  : / +1ms
  express:router <anonymous>  : / +0ms
handling request for:  / POST
xxx passport.use  sss
xxx findByUsername sss
xxx password match
xxx serializeUser { id: 1, username: 'sss', password: 'sss' }
xxx auth success
  express-session saving y4TUFn7tzccSARC7kHiDbuKY8qXj1sCU +13ms
  express-session split response +1ms
  express-session set-cookie connect.sid=s%3Ay4TUFn7tzccSARC7kHiDbuKY8qXj1sCU.yxt3TbHx4HSzm03JMrtPcTPrm3K40FbHiuS6NGT%2Fd7E; Path=/; HttpOnly +3ms
...
  express:router dispatching GET / +14ms
  body-parser:urlencoded skip empty body +0ms
  express:router session  : / +0ms
  express-session fetching y4TUFn7tzccSARC7kHiDbuKY8qXj1sCU +1ms
  express-session session found +1ms
  express:router initialize  : / +1ms
  express:router authenticate  : / +0ms
xxx deserializeUser 1
xxx findById 1
  express:router <anonymous>  : / +1ms
handling request for:  / GET
xxx get root
xxx req.user  { id: 1, username: 'sss', password: 'sss' }
...

As such what is output for the second request in your case is:

xxx deserializeUser 1
xxx findById 1
handling request for:  / GET
xxx get root
xxx req.user  { id: 1, username: 'sss', password: 'sss' }
xxx deserializeUser 1
xxx findById 1

So it's as you expected, but for some reason the session strategy is triggered twice. That I can't reproduce.



来源:https://stackoverflow.com/questions/65374696/why-is-passport-deserializeuser-called-after-req-user-has-been-restored

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!