当前位置: 首页 > news >正文

我是这样搞懂一个神奇的BUG

摘要: 通过分析用户的行为,才想得到为什么会出现这种情况!

前两天在BearyChat收到这样的一个报警消息:

img_7f88669827e722f94d4c32048d6089c9.jpe

409Conflict ? 平时很少遇到这样的错误,貌似很严重的样子,吓得我赶紧查看到底发生了什么。

仔细查看错误详情发现是因为使用同一个邮箱账号多次注册导致后面的请求数据库直接报错。

img_1bcf319cdf1afe63e58cef27b50f81e5.jpe

但是,不应该啊!我们是事先有做检查的。如果该邮箱已经被注册,会提醒并且不让注册的。难道对方是个黑客,直接调用API发请求?如果是这样那就更加危险了,我们已经被黑客盯上了!

可是这样做对黑客也没什么好处啊,并且IP显示为国内地址,如果真的是黑客好歹用国外的地址吧。想了想,还是仔细分析到底出了什么问题吧。

再往下一看,发现自己完全是多想了。如果是黑客的话,下面的用户行为就把他给完全暴露了!

img_48b780623e399866e3bf6a6c74e1e537.jpe

这些用户行为记录默认按照倒序排列,我们可以从下往上一条条看用户的使用轨迹。通过用户行为可以得知出错前的整个操作流程:

  • 打开我们网站的首页
  • 点击“免费试用“进入注册页面
  • 输入邮箱
  • 输入密码
  • 再次出入密码
  • 点击创建团队
  • 点击创建团队
  • 团队创建成功
  • 报错

那么问题来了:有没有什么异常的行为?
答:有!他点击了创建团队两次。

凭着我敏锐的嗅觉意识到可能是由于用户快速点击"创建团队"按钮两次导致。通过时间记录发现第一次点击是在1.86m,第二次在1.87m。也就是说:用户在很短的时间内快速点击了两次。

刚刚的用户行为记录过滤了网络请求,接下里我们结合网络请求一起分析:

img_fdad1d51014e1bfbb1cfe38c6385228e.jpe

可以发现有两个/members/email的GET请求,并且都成功返回404,这里代码的意思是指该邮箱尚未被注册,可以被使用。一个/members/create请求成功返回200,表示账户创建成功。最后报错的/members/create请求失败返回409。

到这里基本确定出错原因就是由于用户快速点击创建团队导致。
有没有这种可能呢,尝试复现一下看看呗!于是,我打开了注册页面,输入邮箱和密码,然后以超快的手速点击创建团队N次。哈哈哈哈,不出所料,被我成功复现了!

只要能够成功复现,这个BUG基本上就算被解决了,接下来就是去分析如何优化代码防止出现这种情况了。有两个思路:1. 用户点击之后,设置被点击的按钮无效直到点击请求完全被处理;2. 将验证邮箱是否存在的和创建团队两个异步事件想办法合并为一个原子操作。综合考虑,决定使用第一种方案。因为实现简单,对现有代码改动不大。

总的来说:当在没有堆栈信息或者报错信息难以理解的时候,Fundebug记录的用户行为真的很有用。五星推荐前端开发接入到项目中!

img_0637837aa0f70d7b099d1ad7c12baf41.jpe

版权声明:
转载时请注明作者Fundebug以及本文地址:
https://blog.fundebug.com/2017/09/06/fundebug-user-behavior-help-debug/

相关文章:

  • C++ 内存泄漏
  • 张星宇:技术人如何打造影响力
  • post方式请求数据
  • 机器学习入门之认知
  • webpack项目中使用grunt监听文件变动自动打包编译
  • jmeter tcp取样器使用方法
  • (六)软件测试分工
  • Java面试题全集
  • 后缀数组专题
  • MySQL查询相关(初级)(全文重点)
  • 堆的实现(图片演示+文字讲解)
  • Ubuntu ko模块的编译
  • 通过git安装npm私有模块
  • python 安装 setuptools Compression requires the (missing) zlib module 的解决方案
  • jquery easyui-datagrid/treegrid 清空数据参考
  • (三)从jvm层面了解线程的启动和停止
  • 《Java编程思想》读书笔记-对象导论
  • 345-反转字符串中的元音字母
  • HashMap ConcurrentHashMap
  • IIS 10 PHP CGI 设置 PHP_INI_SCAN_DIR
  • SpringBoot几种定时任务的实现方式
  • uni-app项目数字滚动
  • 产品三维模型在线预览
  • 从零开始的webpack生活-0x009:FilesLoader装载文件
  • 理解 C# 泛型接口中的协变与逆变(抗变)
  • 深度解析利用ES6进行Promise封装总结
  • 使用Envoy 作Sidecar Proxy的微服务模式-4.Prometheus的指标收集
  • 消息队列系列二(IOT中消息队列的应用)
  • 优化 Vue 项目编译文件大小
  • 云栖大讲堂Java基础入门(三)- 阿里巴巴Java开发手册介绍
  • 再次简单明了总结flex布局,一看就懂...
  • 正则学习笔记
  • 仓管云——企业云erp功能有哪些?
  • ​ArcGIS Pro 如何批量删除字段
  • ​Python 3 新特性:类型注解
  • ​ssh免密码登录设置及问题总结
  • ​低代码平台的核心价值与优势
  • # centos7下FFmpeg环境部署记录
  • #HarmonyOS:软件安装window和mac预览Hello World
  • #stm32整理(一)flash读写
  • #每日一题合集#牛客JZ23-JZ33
  • (C语言)逆序输出字符串
  • (Java实习生)每日10道面试题打卡——JavaWeb篇
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (二)pulsar安装在独立的docker中,python测试
  • (附源码)spring boot儿童教育管理系统 毕业设计 281442
  • (汇总)os模块以及shutil模块对文件的操作
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (强烈推荐)移动端音视频从零到上手(下)
  • (三)终结任务
  • (十六)串口UART
  • (算法)前K大的和
  • (续)使用Django搭建一个完整的项目(Centos7+Nginx)
  • (一)硬件制作--从零开始自制linux掌上电脑(F1C200S) <嵌入式项目>
  • .halo勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复