我目前为我的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/reddit
,req.query.state === req.session.state
的请求。但是,对于http://www.example.com/auth/reddit
发出的请求,这些值不匹配。 req.query.state
获取新的州值,但req.session.state
保留旧的州值。
这个问题是否有良好的解决方法或解决方案?一个解决办法可能是自动将所有'www'请求重定向到根目录,但我还没有找到办法。另一个选择是删除状态检查,但这会打开我的代码来进行CSRF攻击。将所有内容保留为原样不是一种选择,对于用户来说(可以理解)使根域工作非常反直觉但“www”子域不起作用。
谢谢!
答案 0 :(得分:2)
根据我的理解,reddit会根据reddit应用程序设置将用户重定向回非www域,因此您无法使用会话数据。
有两种解决方案:
配置Cookie以使用.mydomain.com
。有关详细信息,请参阅this answer。
忽略状态标志,因为它在OAuth2规范中不是强制性的,尽管建议使用。示例有一个简单的原因,如果状态字段不存在,reddit无法处理请求。至少是在我写图书馆时的情况。您可以随意发送任何随机字符串作为状态值,而无需在返回时检查它。
我个人建议将第一种方法作为默认方法,因为状态标志旨在阻止a certain type of attack。为简单起见,您可能希望采用第二种方法,但只有在您充分了解潜在后果时才这样做 - 这可能会剥夺它的简单性。
答案 1 :(得分:0)
要解决此问题,我正在使用node.js包express-force-domain