node.js - 使用 Express 处理表单的最佳实践

标签 node.js security express body-parser

我正在编写一个实现用户管理系统的网站,我想知道我必须考虑哪些关于表单处理的最佳实践。

尤其是性能、安全性、SEO 和用户体验对我来说很重要。当我处理它时,我遇到了几个问题,但我没有找到一个完整的 Node/表达代码片段,我可以在其中找出我下面的所有问题。

用例:某人要更新他个人资料的生日。现在我正在对同一个 URL 执行 POST 请求以处理该页面上的表单,POST 请求将以 302 重定向响应到同一个 URL。

关于表单处理的一般问题:

  1. 我应该执行 POST 请求 + 302 重定向以处理表单还是执行其他类似 AJAX 请求的请求?
  2. 我应该如何处理无效的 FORM 请求(例如无效的登录名,或电子邮件地址在注册期间已被使用)?

表达有关表单处理的具体问题:

  1. 我假设在将任何内容插入我的数据库之前,我需要清理并验证服务器端的所有表单字段。你会怎么做?

  2. 我阅读了一些有关 CSRF 的内容,但我从未实现过 CSRF 保护。我也很高兴在代码片段中看到这一点

  3. 在使用 Express 处理表单时,我是否需要注意任何其他可能的漏洞?

示例 HTML/Pug:

form#profile(method='POST', action='/settings/profile')
    input#profile-real-name.validate(type='text', name='profileRealName', value=profile.name)
    label(for='profile-real-name') Name

    textarea#profile-bio.materialize-textarea(placeholder='Tell a little about yourself', name='profileBio')
        | #{profile.bio}
    label(for='profile-bio') About

    input#profile-url.validate(type='url', name='profileUrl', value=profile.bio)
    label(for='profile-url') URL

    input#profile-location.validate(type='text', name='profileLocation', value=profile.location)
    label(for='profile-location') Location

    .form-action-buttons.right-align
        a.btn.grey(href='' onclick='resetForm()') Reset
        button.btn.waves-effect.waves-light(type='submit')

示例路由处理程序:

router.get('/settings/profile', isLoggedIn, profile)
router.post('/settings/profile', isLoggedIn, updateProfile)

function profile(req, res) {
    res.render('user/profile', { title: 'Profile', profile: req.user.profile })
}

function updateProfile(req, res) {
    var userId = req.user._id
    var form = req.body
    var profile = {
        name: form.profileRealName,
        bio: form.profileBio,
        url: form.profileUrl,
        location: form.profileLocation
    }

    // Insert into DB
}

注意:非常感谢一个完整的代码片段,它负责适应给定示例的所有表单处理最佳实践。我可以使用任何公开可用的 express 中间件。

最佳答案

Should I do a POST request + 302 redirect for form processing or rather something else like an AJAX request?

,自 2004 年左右(基本上是自 gmail 推出以来)以来,良好用户体验的最佳实践一直是通过 AJAX 提交表单,而不是 web 1.0 整页加载表单 POST。特别是,通过 AJAX 进行的错误处理不太可能让您的用户停留在浏览器错误页面的死胡同,然后通过后退按钮遇到问题。在这种情况下,AJAX 应该发送 HTTP PATCH 请求以使其在语义上最正确,但 POST 或 PUT 也将完成工作。

How should I handle invalid FORM requests (for example invalid login, or email address is already in use during signup)?

无效的用户输入应导致 HTTP 400 Bad Request 状态代码响应,并在 JSON 响应正文中包含有关特定错误的详细信息(格式因应用程序而异,但要么是一般消息或逐个字段的错误是常见的主题)

对于已经在使用中的电子邮件,我使用 HTTP 409 Conflict 状态代码作为一般错误请求负载的更特殊风格。

I assume before inserting anything into my DB I need to sanitize and validate all form fields on the server side. How would you do that?

当然。有很多工具。我通常在 JSON Schema 中为有效请求定义模式并使用 npm 中的库来验证,例如 is-my-json-validajv .特别是,我建议尽可能严格:拒绝不正确的类型,如果必须的话强制转换类型,删除意外的属性,尽可能使用小但合理的字符串长度限制和严格的字符串正则表达式模式,当然要确保你的数据库库属性防止注入(inject)攻击。

I read some things about CSRF but I have never implemented a CSRF protection.

OWSAP Node Goat Project CSRF Exercise是从易受攻击的应用程序开始的好地方,了解并利用漏洞,然后实现修复(在这种情况下,直接集成 express.csrf() 中间件。

Do I need to take care of any other possible vulnerabilities when processing forms with Express?

通常,应用程序开发人员必须了解并积极地安全编码。这方面有很多 Material ,但当用户输入涉及数据库查询、子进程生成或被写回 HTML 时,必须特别小心。可靠的查询库和模板引擎将处理这里的大部分工作,您只需要了解机制和恶意用户输入可能潜入的潜在位置(如图像文件名等)。

关于node.js - 使用 Express 处理表单的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43922205/

相关文章:

javascript - 类型错误 : Cannot read property 'currentQuestions' of undefined in TypeScript

javascript - 使用 vanilla javascript 将 HTML 表导出为 CSV

linux - seccomp-bpf 如何过滤系统调用?

javascript - 在快速中间件中调用时,这在原型(prototype)函数中不起作用

security - 从 docker 容器中执行主机命令

javascript - Node js - 如何安全地将 token 从 http get 请求传递到 html 页面?

javascript - 了解 express.js/sails.js Controller 范围内的下一个中间件

node.js - 带参数的路由被调用两次?

node.js - Nodejs 和 Angular 路由之间可能存在冲突

javascript - 如何让我的数据从 IpcMain 返回