【发布时间】:2014-05-31 21:56:29
【问题描述】:
以下是身份验证流程的细分:
- 用户注册(电子邮件、密码)
- 用户登录
-
如果他们的登录有效,则会在服务器端生成一个令牌,代码如下:
require('crypto').randomBytes(48, function(ex, buf) { var token = buf.toString('hex'); // generates a token, such as.... // 9b50ea46e80804bfe2ae01d0d1bb099c26887a65c92f61e47677c28ed40dbd4ef4c14f0dc58688ab4ec0df6b766ec90f }); 该令牌返回到客户端,并保存为 cookie
- 他们登录的用户IP地址与令牌一起存储到数据库中
-
该令牌存储在数据库中散列,代码如下:
var salt = bcrypt.genSaltSync(10); bcrypt.hash(token, salt, null, function(err, hash) { token = hash; token.save(); // salts and hashes a token and saves that hashed token to the database // resulting hashed token will look like... // $2a$10$rGjMO6bWb/R4/yAAEV8Nx.7Fr6bS.AmMS0vRYB7p5umTpfpjMOfAC }); 在从客户端到服务器的所有未来请求中,“auth_token”标头会自动附加到所有类型的所有请求中,其中包含之前提供给客户端的未散列令牌,该令牌已保存到 cookie
- 当请求进入服务器时,它会检查是否附加了“auth_token”标头
- 如果“auth_token”标头不存在,它会拒绝他们从 API 获取数据的请求
- 如果“auth_token”标头确实存在,它...
- 检查令牌是否有效(通过对数据库中的令牌执行
bcrypt.compare直到找到匹配项来检查令牌是否存在于数据库中)并且是否属于正在与应用程序交互的当前用户(发送请求与附加到数据库中该令牌的用户 ID 匹配) - 检查请求数据的 IP 地址是否与数据库中附加到该令牌的 IP 地址匹配
- 检查令牌是否已过期(在服务器端,而不是客户端 cookie)
- 检查令牌是否有效(通过对数据库中的令牌执行
- 如果上述所有测试都通过,它会为用户提供他们正在寻找的数据...如果它没有通过任何测试,它会给他们一个 403 禁止。
这是我出于学习目的从头开始制作的第一个令牌认证系统。
欢迎提出想法/批评/提问!如果我错过了解释此设置的任何关键部分,请尽管问,我会澄清。
我可以看到有人能够滥用它的唯一方法是:
- 访问某人的计算机
- 从他们的 cookie 中获取他们的令牌
- 在令牌过期前的时间内向 API 发送请求,欺骗用户 IP,使用他们的令牌
- 已授予数据
但为了做到这一点,他们基本上必须访问那个人的计算机才能获取 cookie,如果他们可以访问那个人的计算机,他们基本上已经可以无限制地访问数据仍然存在,因为很可能该人仍在登录网站和/或该人的密码和用户名自动填写在网站上,等等。
【问题讨论】:
-
那是......正是我们不希望在 SO 上出现的响应类型。
-
无论如何,为什么不只使用现有的cookie认证机制?这看起来唯一要添加的是一些额外的“IP验证”。
-
出于了解这些系统如何工作的目的。在应用投入生产之前,我将使用 Passport.js。
-
这种设置不会有会话——后端只是一个分配数据的 API,没有持久连接,只有请求和响应。需要在每个请求上检查身份验证。
-
另外,我编辑了帖子以更好地解释“可疑”部分。
标签: node.js security access-token bcrypt