Passport.js 策略在不使用会话时失败

Posted

技术标签:

【中文标题】Passport.js 策略在不使用会话时失败【英文标题】:Passport.js strategy fails when not using session 【发布时间】:2016-10-21 17:59:49 【问题描述】:

我正在尝试弄清楚如何将 Oauth 策略 (github) 集成到我使用 express 和 websockets 的应用程序中。

我正在关注本指南,该指南解释了如何使用 JWT 令牌而不是使用默认护照会话

https://blog.hyphe.me/token-based-authentication-with-node/

这是我目前的代码

  app.use(passport.initialize())
  app.get('/auth/github',passport.authenticate('github',session:false),serialize, generateToken, respond)

  app.get('/auth/github/callback',passport.authenticate('github',failureRedirect:'/'),
    function(req,res)
      res.redirect('/')
    
  )

当我尝试通过 github 登录时 - 我收到以下错误

Error: Failed to serialize user into session
    at pass (/home/avernus/Desktop/experiments/oauth/node_modules/passport/lib/authenticator.js:271:19)
    at Authenticator.serializeUser (/home/avernus/Desktop/experiments/oauth/node_modules/passport/lib/authenticator.js:289:5)
    at IncomingMessage.req.login.req.logIn (/home/avernus/Desktop/experiments/oauth/node_modules/passport/lib/http/request.js:50:29)
    at Strategy.strategy.success (/home/avernus/Desktop/experiments/oauth/node_modules/passport/lib/middleware/authenticate.js:235:13)
    at verified (/home/avernus/Desktop/experiments/oauth/node_modules/passport-oauth2/lib/strategy.js:177:20)
    at Strategy._verify (/home/avernus/Desktop/experiments/oauth/passport.js:13:12)
    at /home/avernus/Desktop/experiments/oauth/node_modules/passport-oauth2/lib/strategy.js:193:24
    at /home/avernus/Desktop/experiments/oauth/node_modules/passport-github/lib/strategy.js:174:7
    at passBackControl (/home/avernus/Desktop/experiments/oauth/node_modules/oauth/lib/oauth2.js:125:9)
    at IncomingMessage.<anonymous> (/home/avernus/Desktop/experiments/oauth/node_modules/oauth/lib/oauth2.js:143:7)

我不确定问题到底出在哪里

这是我的 github 策略

passport.use(new githubStrategy(
  clientID:'********',
  clientSecret:'*******',
  callbackURL:'http://localhost:3000/auth/github/callback'
  ,
  function(accessToken,refreshToken,profile,done)
    console.log('accessToken: ',accessToken,' refreshToken: ',refreshToken,' profile: ',profile)
    return done(null,profile)
  
))

我能够从 github 成功获取配置文件

序列化函数

function serialize(req, res, next)   
  db.updateOrCreate(req.user, function(err, user)
    if(err) return next(err);
    // we store the updated information in req.user again
    req.user = 
      id: user.id
    ;
    next();
  );

【问题讨论】:

请发布您的序列化函数,因为这是您的错误所关注的问题。 @GibryonBhojraj - 我没有为此使用标准的 serializeUser。我将使用相关功能更新问题 【参考方案1】:

你是不是错过了回调中的 session:false 选项?

app.get('/auth/github/callback',passport.authenticate('github',failureRedirect:'/', session: false),
function(req,res)
  res.redirect('/')
)

我在这里猜测是因为我从未使用过需要回调的策略。但我想护照会尝试在回调中序列化用户,因为这就是您从 Github 接收配置文件的地方。

【讨论】:

【参考方案2】:

根据我的经验,使用 oauth 的 passportjs 总是需要会话才能运行,尽管 session: false 选项。

我相信底层 oauth 库依赖项无论如何都会寻找会话。这很令人沮丧。

编辑:要为此添加更多详细信息,您要链接到的示例使用默认策略,该策略不基于 oauth。在这种情况下,您可以选择不使用会话。您正在使用使用 oauth 的 github 策略,因此需要会话

【讨论】:

我假设本地和社交都将遵循相同的 api :/。太烂了 您实际上只“需要”初始 oauth 握手的会话。完成后,您可以使用令牌和反序列化中间件/处理程序恢复正常操作。如果我记得,在没有会话 cookie 的情况下拨打电话时,由于缺少会话,您可能会收到错误消息。我相信我的解决方法是捕获请求并在其中创建一个带有 passport: 的虚拟会话对象,以满足会话的存在。 有一个关于使用 JWT 和 Oauth2 的堆栈溢出问题 - ***.com/questions/11458364/… 使用 jwt 和 oauth 本身并不困难/有问题,但我相信 OPs 问题的根源在于通过 passportjs 及其依赖项实施该策略。 是的,即使会话被禁用,护照似乎也在调用 serializeUser,这意味着它不是 github 策略的选项。

以上是关于Passport.js 策略在不使用会话时失败的主要内容,如果未能解决你的问题,请参考以下文章

Passport js 无法跨域维护会话

使用 Android 登录时未设置 Passport.js 会话

如何使用 cookie-session 和 passport.js 在注册时启动会话?

Okta 是不是使用 Passport.js?

Passport.js Google 策略不适用于 React 应用程序

Passport.js 身份验证失败时发回 JSON 响应