《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
关于 LearnKu
高认可度评论:
3L 说了前端的方法,我说说后端的方法吧。
新建一个中间件:
前端页面
crsf?@zedisdog 不行,这个好像是用来验证表单来源是否为本站的,并没有做重复提交处理
@深蓝色 那就不知道了,按理说重复提交的问题应该前端来解决。比如,提交按钮按了就不能再按了之类的。
3L 说了前端的方法,我说说后端的方法吧。
新建一个中间件:
前端页面
@DavidNineRoc 感觉你的代码有BUG
@DavidNineRoc 有问题,假设前端页面不止一个表单,怎么区分不同表单的提交呢?
@Littlesqx 解释一下吧,免得更多的人问。
路上下雨,手机码字就暂时写这么多吧!
@DavidNineRoc 嗯,明白了。还有一个问题,如果有人恶意提交(模拟改变 form_token 的值,不断请求)。那后端就不断地存,session 会不会爆炸?
@Littlesqx Cache
时间短一点,一起提交过来的还有 csrf_token
如果使用 Laravel 用户认证 的包,则自动加载了登录限制: 用户认证《Laravel 5.6 中文文档》
或者也可以直接使用路由上的频率限制: 路由《Laravel 5.6 中文文档》
@DavidNineRoc 这样行不通吧...
前端每次提交都会生成新的 token , 这个新的 token 在你的中间件里面被接收, 所以 if 判断永远都是 false, 做的是无用功啊 :joy:
@weir 你可能需要看一下题目说的是 防止重复提交,而不是多次提交。
重复提交我的定义是:单次的数据提交多次,更多是出现在 AJAX 提交。比如下订单,你点了,网络可能延迟一秒,前端也没有禁用按钮,然后你以为出 bug,然后一直点。这一秒延迟你点了十次,如果你不做验证,就会有十条订单记录。而如果用我说的那个方式,实际上发到后端的都是 form_token,后面的九次都是重复提交的,直接不进入控制器就行了
@DavidNineRoc 这个中间件并不能防止你定义的重复提交. 一秒点十次, 这十次前端提交过来的表单都会携带不同的 token , 也就是说你在中间件里面接收到 token 每次都是不一样的 , if 里面的代码永远都不会起作用.
@DavidNineRoc 你在 if 里面 dd() 测试一下就明白我的意思了
@weir 我写的代码我不清楚,我不知道你为什么会有十次 token 不同?为什么点击十次就会有十个 token?你觉得 token 是在什么时候生成的? 素质三问。
@DavidNineRoc 不要激动啊
楼主并没有指定表单的环境是浏览器还是其它的, web 上我没有测试 , 也许可以 . 我在小程序里面试了一下, 确实不起作用.
首先
这个和小程序什么没有任何关系。
你在页面加载的时候生成一个 form_token,只在页面加载时生成,那么其他时候就只会用这一个,那么只要你没有刷新页面,那么就永远不会变,当你提交的带上这个参数提交到后台。 那么你是觉得为什么做不到呢?
@DavidNineRoc 好吧, 是我错了. 没搞清楚你说的重复提交和多次提交的区别. 我测试的时候用了一个表单, 提交相同的内容, 按照你的定义, 属于 多次提交 .
有办法直接利用内置的那个token吗,感觉弄两个名称相似的Token好诡异
1 如果防止表单重复提交我觉得csrf是比较好的方式
2 如果防止数据重复我觉得可以可以在数据库上加上唯一索引 (你觉得要重复的的数据) 然遇到重复的就会抛出异常 这个有点暴力 但是能解决问题 也可以考虑redis存md5
csrf并没有提供重复提交的机制
我觉得比较好的做法是通过中间件,请求到来的时候查询redis中是否有根据请求参数、请求路径、ip等变量拼接后加密的md5值(或其他可以唯一识别的值),如果存在,判定为重复请求,如果不存在就往redis中新增,中间件通过后,执行完业务,再通过Terminable中间件将这个值从redis中删除
@DavidNineRoc 老铁这个方法会不会被人恶意提交 session 被干爆啊
@sniffrose 不会
这个方法其实可以实现这个功能,需要做一点修改,将前端token记录到cache,下次请求比对两次token是否相等,相等则提示重复,不同则可以继续后续操作。
第一步,用户打开表单,在后端生成一个 token 保存在 session 中,并渲染到表单
第二步,表单提交时,匹配 token 有效则执行,执行后清除 session 中的 token