使用“www”子域中的Reddit OAuth进行身份验证时出现问题

时间:2013-12-05 01:14:38

标签: node.js oauth passport.js reddit

我目前为我的Node应用程序设置了Reddit授权,就像在this example中一样。我在Reddit上设置了回调网址http://example.com/auth/reddit/callback的应用程序,一切都很好。用户可以输入http://example.com/auth/reddit并登录,一切都很好。

当用户尝试通过http://www.example.com/登录时,会出现此问题。似乎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/redditreq.query.state === req.session.state的请求。但是,对于http://www.example.com/auth/reddit发出的请求,这些值不匹配。 req.query.state获取新的州值,但req.session.state保留旧的州值。

这个问题是否有良好的解决方法或解决方案?一个解决办法可能是自动将所有'www'请求重定向到根目录,但我还没有找到办法。另一个选择是删除状态检查,但这会打开我的代码来进行CSRF攻击。将所有内容保留为原样不是一种选择,对于用户来说(可以理解)使根域工作非常反直觉但“www”子域不起作用。

谢谢!

2 个答案:

答案 0 :(得分:2)

根据我的理解,reddit会根据reddit应用程序设置将用户重定向回非www域,因此您无法使用会话数据。

有两种解决方案:

  1. 配置Cookie以使用.mydomain.com。有关详细信息,请参阅this answer

  2. 忽略状态标志,因为它在OAuth2规范中不是强制性的,尽管建议使用。示例有一个简单的原因,如果状态字段不存在,reddit无法处理请求。至少是在我写图书馆时的情况。您可以随意发送任何随机字符串作为状态值,而无需在返回时检查它。

  3. 我个人建议将第一种方法作为默认方法,因为状态标志旨在阻止a certain type of attack。为简单起见,您可能希望采用第二种方法,但只有在您充分了解潜在后果时才这样做 - 这可能会剥夺它的简单性。

答案 1 :(得分:0)

要解决此问题,我正在使用node.js包express-force-domain

见这里:https://stackoverflow.com/a/12755464/1222411