【问题标题】:How can I prevent a user from accessing a route via URL parameters?如何防止用户通过 URL 参数访问路由?
【发布时间】:2021-10-12 13:46:48
【问题描述】:

我正在编写一个 Express 应用程序,它根据用户从两个下拉列表中所做的选择来创建和导出文档。按下按钮后,下拉值作为路由参数传递,然后在路由方法中调用必要的函数来创建文档并将其发送回用户。

如何通过在 URL 栏中手动输入路由参数来防止用户(如果可能)调用/访问此路由?他们应该只能通过按下按钮访问路线。

以下是我的应用程序功能的一些通用代码...

按钮点击后获取/发送值的代码:

export.onclick = function() {
    let index1 = dropdown1.value;
    let index2 = dropdown2.value;

    fetch('/' + index1 + '/' + index2)
    // Convert response to blob object for download
}

路线代码:

app.get('/:index1/:index2', function (req, res) {
    // Call functions to create document
    // Return document back to user
});

下拉列表是使用从 API 响应中获得的数据动态填充的。每个下拉选项的值代表该选项的索引。能够输入随机索引的用户允许无效输入;但是,输入不一定有边界,因为下拉列表是根据各种用户限制动态填充的。出于这个原因,通过在我的脑海中输入参数来防止用户能够访问路线是理想的。

【问题讨论】:

  • 在浏览器的地址栏中输入 URL 通常会向您的应用程序创建一个GET 请求。因此,如果您将注册的 GET 处理程序更改为 POST 一个 ...并在您的 fetch 调用中使用 Method POST ... 那么您应该很好。

标签: javascript node.js express


【解决方案1】:

您无法取消在浏览器地址栏中输入 URL 的功能,但您可以决定不在后端处理生成的 GET 请求。相反,您可以监听 POST 请求。

app.post('/:index1/:index2', function (req, res) {
    // Call functions to create document
    // Return document back to user
});
export.onclick = async function() {
    let index1 = dropdown1.value;
    let index2 = dropdown2.value;

    const response = await fetch(`/${index1}/${index2}`, {
      method : 'POST'
    });
}

这绝不是一项安全功能,如果用户知道自己在做什么和/或使用像 POSTMAN 或类似的请求客户端,用户仍然可以手动创建POST 请求.

但是为什么?

在我看来,这可能是一个 XY 问题。为什么要阻止用户在地址栏中手动输入 URL?它会以任何方式损害您的服务器/业务吗?如果是,那么你手头有一个不同的、更大的问题。

【讨论】:

  • 我想这就是我想要的。我想防止用户手动输入到 URL 栏以防止无效输入,并防止用户“跳过”UI 功能。显然,验证输入通常不是以这种方式完成的。但是,无需过多详细介绍,我设计应用程序的方式使该解决方案发挥最佳效果。使用 Postman 绕过它不会返回任何对用户有用的东西,因此不必担心它是一个安全问题。
【解决方案2】:

添加一个令牌以保护您在服务器端的 get 请求

喜欢这个

app.get('/:index1/:index2', function (req, res) {
    if (req.query.token !== 'foo') {
      // invalid the request
    }
    // Call functions to create document
    // Return document back to user
});

要向 url 发送请求,您需要令牌

/:index1/:index2?token=foo

或者只是在请求头上添加令牌

那么下面的问题可能是

我是否需要动态令牌来保护/:index1/:index2 API?

如果否,则用户仍然可以使用此固定令牌键入 URL

如果是,您将需要另一个 API 在“按钮页面”上生成令牌

fetch('/get_new_token')
// get the token via this API
const token = ...

export.onclick = function() {
    let index1 = dropdown1.value;
    let index2 = dropdown2.value;

    fetch('/' + index1 + '/' + index2 + '?token=' + token)
    // Convert response to blob object for download
}

您可以使用密钥来加密您的令牌

或在您的令牌中添加签名以验证令牌没有被修改

如果您希望您的令牌在时间戳后过期

在令牌中添加时间戳信息

然后在服务端验证时间戳

【讨论】:

    猜你喜欢
    • 2021-10-05
    • 2020-02-22
    • 2019-08-24
    • 1970-01-01
    • 2021-10-08
    • 1970-01-01
    • 2016-08-26
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多