如何在节点 js express 中添加密码检查中间件

How do I add a password checking middleware in node js express

我正在尝试制作一个中间件,它显示一个要求输入密码的表单。

问题是我在 get 路由中,我无法在 get 请求中传递数据,因为我不想在 url 中传递密码。所以我尝试制作一个中间件,它显示一个带有隐藏信息的表单,比如客户想要访问的聊天 ID 提交到另一个路由 (post)。在 post 路由中,它检查密码是否正确,如果密码正确,则返回原始路由 (get) 并显示聊天。

这是我到目前为止所做的:

GET 路由:

router.get('/chats/:id', middleware.isLoggedIn, middleware.isAllowed, catchAsync(async (req, res, next) => {
    const foundChat = await Chat.findOne({
      _id: req.params.id
    })
    console.log('here', foundChat)
    res.render('chat/show', {
      chat: foundChat
    })
}))

POST路线

router.post('/chats/password', middleware.askForPassword)

中间件

middleware.isAllowed = async function (req, res, next) {
  if (req.cookies.allowed) {
    if (req.cookies.allowed.includes(req.params.id)) {
      req.body.password = null
      return next()
    }
  } else {
    res.redirect('/chats/password')
  }
}
middleware.askForPassword = async function (req, res, next) {
  try {
    const hashedDBPassword = await Chat.findById(req.params.id)
    const password = req.body.password
    const passwordHashed = hashedDBPassword.password
    const cookieName = encodeURIComponent(hashedDBPassword.name)
    const resultCompare = await bcrypt.compare(password, passwordHashed)
    let value
    if (req.cookies.allowed === undefined) {
      res.cookie('allowed', [], {
        maxAge: 30000,
        httpOnly: true
      })
    }
    if (resultCompare === true) {
      value = req.cookies.allowed
      value.push(passwordHashed)
      res.cookie('allowed', value, {
        maxAge: 30000,
        httpOnly: true
      })
      res.redirect('/chats/' + req.body.id)
    } else {
      global.nextMiddleware = true
      res.render('chat/password', {
        id: req.body.id
      })
    }
  } catch (err) {
    console.log(err)
    res.redirect('/chats')
  }
}

形式

<% layout("layouts/boilerplate.ejs") %>
<form action="/chats/password" method="post">
<input type="password" name="password" id="password">
<input type="hidden" name="id" value="<%= id %>">
<input type="submit" value="Go!">
</form>

如果您希望代码为 RESTful,那么路线可能如下所示:

POST /auth
GET /auth
GET /auth/:sessionId
DELETE /auth/:sessionId
GET /chat/:chatId

方法POST /auth,应该给客户端设置授权cookie和return sessionId。客户端可以将 sessionId 放入 localStorage。也可以有可选的参数redirect,它可以将成功的请求重定向到指定的URL。但是你应该小心使用它,并且不允许重定向到外部主机。

方法GET /auth 列出当前用户打开的所有实时会话。当您需要关闭其他设备上的会话时,它可能会有所帮助。

方法 GET /auth/:sessionId returns 会话的 ID。它可以包含有关会话的信息,例如上次 activity、设备(浏览器或移动设备)等

方法 DELETE /auth/:sessionId 从路由接收 sessionId,使用授权 cookie 验证会话所有权,在数据库中标记会话关闭(如果您将会话存储在数据库中),并删除授权 cookie。

方法 GET /chat/:chatId 仅依赖 HTTP 授权 cookie(像现在一样工作)。

您可以从前端通过 XHR 发送 POST 请求,收到成功的响应,然后导航到聊天。