在“www”子域中使用Reddit OAuthvalidation问题

我现在已经为我的Node应用程序设置了Reddit授权,就像本例中一样 。 我有在Reddit设置callbackurlhttp://example.com/auth/reddit/callback的应用程序,一切都很好。 用户可以inputhttp://example.com/auth/reddit并login,一切都很好。

用户尝试通过http://www.example.com/login时出现问题。 看起来,Reddit的CSRF保护将这些请求视为一个问题。 按照这个例子:

 /** * Authentication route */ app.get('/auth/reddit', function(req, res, next) { var n = crypto.randomBytes(32).toString('hex'); req.session.state = n; passport.authenticate('reddit', { state : n, duration : 'permanent' })(req, res, next); }); /** * Authentication callback */ app.get('/auth/reddit/callback', function(req, res, next) { // Check for origin via state token if (req.query.state === req.session.state) { /* authenticate the user */ } else { next(new Error(403)); } } 

对于来自http://example.com/auth/reddit请求, req.query.state === req.session.state 。 但是,对于http://www.example.com/auth/reddit发出的请求,这些值不匹配。 req.query.state采用新的状态值,但req.session.state保留旧的状态值。

有没有一个很好的解决方法或解决这个问题? 一个解决方法可能是自动将所有'www'请求redirect到根,但我还没有find一个方法来做到这一点。 另一个select是删除状态检查,但这会打开我的代码到CSRF攻击。 保留所有内容不是一种select,对于用户来说,(可以理解)非常不直观地让根域工作,但“www”子域不起作用。

谢谢!

据我所知,按照reddit应用程序设置,reddit会将用户redirect回非www域,因此您的会话数据不可用。

有两个解决scheme:

  1. configurationCookie以使用.mydomain.com 。 看到这个答案的细节。

  2. 忽略状态标志,因为它在OAuth2规范中不是强制性的,尽pipe推荐。 例子有一个简单的原因,如果状态字段不存在,reddit无法处理请求。 我在写图书馆的时候至less是这样。 您可以随意发送任何随机string作为状态值,而不会在返回时检查它。

我个人推荐第一种方法作为默认方法,因为状态标志旨在防止某种types的攻击 。 为简单起见,您可能想要采用第二种方法,但是只有在充分了解潜在后果的情况下才可以这样做 – 这可能会降低简单性的价值。

为了解决这个问题,我使用了node.js包express-force-domain

看到这里: https : //stackoverflow.com/a/12755464/1222411