当浏览器重新加载/返回时,如何防止数据库再次写入? [英] How can I prevent database being written to again when the browser does a reload/back?

查看:307
本文介绍了当浏览器重新加载/返回时,如何防止数据库再次写入?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我把一个小的web应用程序写入数据库(Perl CGI& MySQL)。 CGI脚本从表单中获取一些信息并将其写入数据库。但我注意到,如果我在Web浏览器上点击重新加载或返回,它会再次将数据写入数据库。我不想要这个。

I'm putting together a small web app that writes to a database (Perl CGI & MySQL). The CGI script takes some info from a form and writes it to a database. I notice, however, that if I hit 'Reload' or 'Back' on the web browser, it'll write the data to the database again. I don't want this.

在这种情况下,防止重新写入数据的最佳方法是什么?

What is the best way to protect against the data being re-written in this case?

推荐答案

不要使用GET请求进行修改!成为 RESTful ;请使用POST(或PUT),而不是浏览器警告用户不要重新加载请求。在POST / POST之后,使用正常的GET请求将(使用HTTP重定向)重定向到收据页面, PUT请求可以刷新页面,而不会再次提交警告。

Do not use GET requests to make modifications! Be RESTful; use POST (or PUT) instead the browser should warn the user not to reload the request. Redirecting (using HTTP redirection) to a receipt page using a normal GET request after a POST/PUT request will make it possible to refresh the page without getting warned about resubmitting.

编辑:

我假设用户以某种方式登录,因此您已经有一些跟踪用户的方式,例如会话或类似

I assume the user is logged in somehow, and therefore you allready have some way of tracking the user, e.g. session or similar.

当显示表单时,可以创建时间戳(或随机散列等),将其作为隐藏字段存储(反网站请求令牌我确定你已经有在那里),并在会话变量(它被安全地存储在您的服务器上),当您收到此表单的POST / PUT请求,你请检查时间戳是否与会话中的时间戳相同。如果是,您将会话中的时间戳设置为某些变量,很难猜测(时间戳与某些保密字符串连接),那么您可以保存表单数据。如果有人现在重复请求,您将不会在会话变量中找到相同的值,并拒绝请求。

You could make a timestamp (or a random hash etc..) when displaying the form storing it both as a hidden field (just besides the anti Cross-Site Request token I'm sure you allready have there), and in a session variable (wich is stored safely on your server), when you recieve a the POST/PUT request for this form, you check that the timestamp is the same as the one in session. If it is, you set the timestamp in the session to something variable and hard to guess (timestamp concatenated with some secret string for instance) then you can save the form data. If someone repeats the request now you won't find the same value in the session variable and deny the request.

这样做的问题是,如果用户点击返回更改某些内容,表单就会无效,这可能会有点苛刻,除非你的钱更新。所以如果你有愚蠢的用户刷新和点击后面的按钮,从而意外重新发布的东西,只是使用POST的提醒他们不要这样做,并重定向将使其不太可能的问题。如果你有恶意用户的问题,你应该使用一个时间戳太多,虽然它会混淆用户有时,即使用户故意张贴相同的消息,你可能需要找到一种方法来禁止他们。使用POST,拥有一个时间戳,甚至对整个数据库进行完全比较以检查重复的帖子,如果恶意用户只是编写一个脚本来加载表单并自动提交随机垃圾,将无济于事。 (但跨站点请求保护使得更困难)

The problem with doing this is that the form is invalid if the user clicks back to change something, and it might be a bit to harsh, unless it's money you're updating. So if you have problems with "stupid" users who refresh and click the back-button thus accidentally reposting something, just using POST would remind them not to do that, and redirecting will make it less likely. If you have a problem with malicious users, you should use a timestampt too allthough it will confuse users sometimes, allthough if users is deliberately posting the same message over and over you probably need to find a way to ban them. Using POST, having a timestam, and even doing a full comparison of the whole database to check for duplicate posts, won't help at all if the malicious users just write a script to load the form and submit random garbage, automatically. (But cross-site-request protection makes that a lot harder)

这篇关于当浏览器重新加载/返回时,如何防止数据库再次写入?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆