4

我有一个在 mongoose 和 express 上运行的 node.js REST 服务。我也在使用 merse 来设置我的路由。

我现在想要实现的是以下类型的场景:

Scenario I: e.g. blogpost
- GET -> no authentication required
- POST/PUT/DELETE -> authentication required

Scenario II: e.g. user
- GET -> authentication required
- POST/PUT/DELETE -> authentication required plus username of logged in user has to match

我已经看过everyauth 和mongoose-auth,但找不到任何可以让我进行这种控制的东西。

4

1 回答 1

15

忘记一切。这个图书馆是一个矫枉过正,恕我直言。实现身份验证实际上非常简单,遵循架构:

  1. 用户通过usernamepassword到服务器;
  2. 服务器获取usernamepassword检查数据库中是否有用户password。如果没有用户,则返回错误;
  3. 我们有一个用户,现在使用 Express 的内置会话机制。调用req.session.regenerate并在回调中做req.session.userID = user.id. Express 会自动将 cookie 发送给用户;
  4. 创建一个中间件(必须在任何其他请求处理程序之前触发),它基本上在数据库中搜索req.session.userID. 如果找到,则将其存储在 中req,即req.user = user
  5. 在视图中,您只需检查是否req.user设置了变量。如果是,那么我们就通过了身份验证。你完成了!

ad 1+2) 为了确保身份验证安全,您应该使用一些密码学(和/或 HTTPS)。例如,密码应分两部分保存在 DB 中:salthash. salt是随机生成的(在注册时)hash = hash_it(pwd, salt),其中hash_it是一些散列算法(例如:MD5 或 SHA256)。

现在可以通过几个步骤进行客户端身份验证(仅当您可以使用 JavaScript 时):

  1. 服务器随机发送new_salt到登录页面(或者用JavaScript生成一个,不需要隐藏生成算法);
  2. 用户发送 AJAX 请求give me salt for user X,服务器以salt存储在 DB 中的数据进行响应(这salt是公开的);
  3. 在响应散列pwdsalt然后再次散列结果new_salt,将其存储在变量中hpwd
  4. 客户端将username,hpwd和发送new_salt到服务器;
  5. 服务器pwd从 DB 中获取,与结果进行username散列并将结果与​​(注意:您不存储)进行比较。pwdnew_salthpwdnew_salt

这种方法很好,因为每次登录时都会随机(从外部角度)数据流过网络,即使 theusername和 thepassword是相同的。

这很重要,因为password泄漏是一件很严重的事情。不是因为有人可以破坏您的应用程序的帐户(这是轻微的损害,除非您是银行 - 但是您不会问这样的问题 :D )。主要是因为人们倾向于对多个网站使用相同的密码,包括银行账户。

于 2012-06-25T10:28:29.667 回答