在 MVC 中检索数据的最佳实践:使用 POST 进行检索和令牌处理的问题 [已关闭]

Best Practices for retrieving data in MVC: Concerns about Using POST for Retrieval and Token Handling [closed]

提问人:noMoreBeans 提问时间:11/14/2023 最后编辑:noMoreBeans 更新时间:11/14/2023 访问量:52

问:


想改进这个问题吗?更新问题,以便可以通过编辑这篇文章用事实和引文来回答。

5天前关闭。

我目前正在开发一个 MVC 应用程序。我已经使用 POST 方法实现了一个路由来检索信息并导航到相应的页面,并且我对我使用的设计实践有一些担忧。 这是路线:

app.post('/metrics/service/:serviceId', async (req, res) => {
        target = req.query.target;
        errors = [];
        if (!target) {
            res.render('metrics', {error: 'Please select a target to get the metrics from'});
        }else{
            await MetricsService.getServiceDetails(req.params.serviceId, target, req.body.token).then((data) => {
                const mermaid_diagram = MetricsService.getMermaidServiceDiagram(data);
                res.render('metrics_service_details', {target: target, mermaid_diagram, data, cnt: 0, errors: errors})
            }).catch((error) => {
                res.status(500).send('Error: ' + error);
            }); 
        }
    });

关于这种实现,我有几个顾虑:

  • 使用 POST 进行检索:使用 POST 方法检索数据是否是一种好做法?我是否应该考虑将其更改为 GET 方法?

  • 处理 URL 中的令牌:身份验证所需的令牌作为请求正文 (req.body.token) 的一部分传递。如果我将方法更改为 GET,我会担心 URL 中有令牌的安全性。什么是更安全的方法?通过标头或任何其他推荐的方法传递令牌更好吗?

  • URL 参数和正文数据的组合:目前,我使用的是 URL 参数 (serviceId)、查询参数 (target) 和请求正文中的令牌的组合。这种方法是否可以接受,或者我应该修改它以保持更一致的方法?

我非常感谢有关如何构建此 MVC 路由以实现高效和安全的数据检索的见解和最佳实践。

谢谢!

我尝试了几种方法,它们都按预期工作,但我担心的是最佳实践。

Express 设计模式 架构 http-method

评论

1赞 philipxy 11/22/2023
请提出 1 个经过研究的非重复问题。如何向帮助中心提问 为什么询问有关“最佳实践”的问题是一件坏事? “哪个更好”问题的策略工程学中没有“最好”。你是如何根据你的标准进行评估的?您期望我们如何告诉您该怎么做,而没有足够清楚地告诉他们所有人都会同意估值?(修辞。
0赞 noMoreBeans 11/22/2023
@philipxy对不起,但你为什么要删除我对答案的回复?我感谢某人并提供上下文说明为什么这个“基于意见的问题”对于构建一个好的应用程序很重要,这是否会伤害任何人?我对最近的编辑和反馈感到沮丧。最佳实践在工程设计中对于效率、可读性和安全性至关重要。取消对此的讨论会破坏有价值的知识共享。工程中有“最佳实践”。如果没有,则有关于优点和缺点的事实(即 POST 不缓存)。这对社区很有帮助。
0赞 philipxy 11/22/2023
我不知道你说的“我对答案的回复”是什么意思(对答案帖子的评论?),我没有,也无法删除任何东西,我不记得在这里标记过任何东西。我依稀记得也许曾经有 2 条关于答案的评论,但我没有读过。回答者对 Meta Stack Overflow 的审核有积极的咆哮,所以也许这与它有关。如何提问 如何回答 帮助中心 Meta Stack Overflow Meta Stack Exchange 请了解该网站的运作方式。请根据我的评论采取行动。
0赞 philipxy 11/22/2023
我在谷歌缓存中发现了 2 条答案评论。评论是短暂的。它们用于发布澄清请求和改进问题。因此,这 2 条评论“不再需要”(实际上从未需要),因此它们被删除也就不足为奇了。用户发表评论以教育,但当这与未决的帖子问题无关时,它也是在阅读之后或之前的 NLN。

答:

1赞 Julio Di Egidio 11/14/2023 #1

使用 POST 进行检索:这是一种好的做法吗 使用 POST 方法检索数据?我应该 考虑将其更改为 GET 方法?

除非您受到特定的约束(我想到了 REST),否则主要目标是组件接口(API 的)整体统一性,并且在有理由时使用 POST 来检索数据就可以了:首先,如果我们需要传递带有请求的正文,这是我们不得不做的事情, 因为从理论上讲,主体也可以附加到 GET 请求,但框架可能不尊重这一点: 我不确定 Express.js,但例如 ASP.NET MVC 没有(至少我上次检查时,大约一年前),即控制器方法(请求处理程序)接收的正文对于 GET 请求始终为空。

不过,使用 POST 并不等同于使用 GET,我能想到的主要含义是:

  • 除非您还使用适当的响应标头,否则不会缓存对 POST 请求的响应,即使在这种情况下,情况也类似于在 GET 请求中使用正文,浏览器(直到今天)实际上可能并不遵守缓存标头,因此最好不要依赖它:有关更多详细信息,请参阅此线程: 是否可以在 HTTP 中缓存 POST 方法?

  • 从浏览器重新加载结果页面会导致“重新发布请求”警告,这是糟糕的用户体验(大多数用户甚至不知道发生了什么),此外,如果请求处理程序(控制器方法)执行实际工作而不仅仅是检索数据,则可能会有很大的问题,在这种情况下,需要幂等性方案(例如,不要仅仅因为用户点击重新加载并确认而两次提交相同的订单)。

考虑到这些问题,一个有意义的最佳实践,即实际上涉及用户及其体验,而不是编程访问(严格意义上的 API),而是通过从 POST 处理程序重定向到普通 GET 资源来响应。

处理 URL 中的令牌:所需的令牌 身份验证作为请求正文的一部分传递 (req.body.token)。 如果我将方法更改为 GET,我是 通过在 URL 中包含令牌来关注安全性。 什么是更安全的方法?是不是更好 通过标头或任何其他推荐的方法传递令牌?

对于在纯 HTTP 下提供的页面,将敏感数据放在请求的标头中、在查询字符串中和在正文中之间没有区别,并且最常见的(如果不是规范的)令牌和类似内容是使用标头:只是不要将其放在地址本身中,即作为 URL 路径的组成部分, 因为如果升级到 HTTPS,则 URL 路径加密。我说没有区别,因为任何至少可以使用PostMan或网络嗅探器等工具的用户都可以轻松访问所有这些内容。

另请注意,在纯 HTTP 下,查询字符串(与其他所有内容一样)未加密,不仅服务器,浏览器和干预代理都可能记录和缓存整个 URL 下的资源,包括查询字符串。

当然,这里的最佳做法是在任何情况下都使用 HTTPS,但要注意的是,HTTPS 加密本身并不难破解,这就是更强大的身份验证工作流程的原因,例如 JWT(我非常推荐),其中至少攻击面被最小化:一个身份验证事件,然后是一个聪明的方案,用于传递相当于对称加密且通常是临时令牌的等效物。(我不是密码学专家,我希望我在这里不要简化太多。

URL 参数和正文数据的组合: 目前, 我使用了 URL 参数 (serviceId) 的组合, 查询参数 (target) 和请求中的令牌 身体。这种方法是否可以接受,或者我应该修改它 保持更一致的方法?

I think it is perfectly legitimate, the main indication here is "make it make sense", to you who are writing it (ideally as reflected by some specification on top), as well as to users of those methods and of your component interface overall. In your example, I'd read it that the resource (its "identity") is the whole URL together with the serviceId, while the body of the request is about what I want to do and/or be done with it.

I'd greatly appreciate insights and best practices on how to architect this MVC route for efficient and secure data retrieval.

Efficiency as in performance is quite independent of all of the above: anyway, as far as I can tell (short of inspecting framework source code), there is no significant difference between pre-processing a POST request by the framework (Express.js or else) vs pre-processing a GET request.

评论

0赞 noMoreBeans 11/14/2023
Thank you so much for your detailed response. Regarding the last part of your comment, I meant to say "best of practices" instead of performance "efficiency" (english is not my first language). Even though my post was downvoted (-1 at moment I'm writing this) I think your comment proves that the question itself is not dumb or irrelevant. As a junior developer, I really appreciate your effort to explain all of it.
0赞 Julio Di Egidio 11/14/2023
You are welcome and I'm glad that helped. Indeed, I find your question legitimate and even well presented: but I am too new to SO to even comment on your question, let alone feel confident about taking any action.