背景
最近项目开发进入了前后端联调阶段,这次是和小程序前端与PHP后端进行联调,场景是前端输入手机号进行发送手机验证码,输入3次以后要进行图形验证码输入,防机器人暴力枚举
场景流程
- 前端请求手机验证码发送接口
- 后端判断手机号是否注册
- 3次无验证判断后,第四次请求会触发验证码验证
- 前端请求验证码controller
- 后端生成验证码,放到session中,然后直接输出一张图片到浏览器中
- 前端带上验证码,再次请求手机验证码发送接口
- 后端验证传来的验证码,通过之后再进行手机号验证
遇到的问题
在本地postman进行测试的时候,万事大吉,但是一放到测试环境进行联调的时候,发现服务端session获取不到,是个null
联调bug排查
详细排查步骤如下
1.看log
原本想用phpstorm进行远程debug,但是由于测试服务器没办法直接访问,要使用跳板机才可以访问,只能用查看log的方式去排查问题
在代码里面加log,记录每次生成的captcha(服务端生成的验证码)以及用户输入的code,本次postman测试远程测试环境依旧OK,但是前段请求的时候,发现captcha每次都可以正常的生成,但是获取的为null
2.前端排查
前端排查,前端能请求到后端接口,验证码也能正常生成,初步判断应该不是前端的问题
3.后端排查
后端在本地测试OK,测试环境用postman也是OK的,感觉上也是没问题的
4.深入分析
后端可以正常访问,postman测试本地和测试服务端也是通过的,我觉得后端应该是没问题的,但是前端也说他那边的请求没问题,感觉很不合理。
于是便深入想了一下session的机制根据session的机制,服务端的session是用sessionid对session进行区分的,如果是前端能正常进行请求,后端可以生成,这个过程是通的,不通的就是第二次前端把code发过来和后端的captcha比较的时候,后端的captcha为null,那很有可能是因为两次的请求sessionid的不一致导致的
5.资料查阅
发现果然是这个原因,由于微信小程序的请求是先通过微信的服务器,然后再由微信的服务器转发到我们的接口的,而且是不带cookie的,所以每次请求后端的接口的时候sessionid都是不一样的,这样导致了之前出现的验证码正常生成,验证阶段的时候获取不到的原因
6.问题解决
既然我们不能用session,我们就可以使用redis模拟一个session,具体思路如下
- 前端请求手机验证码发送接口
- 后端判断手机号是否注册
- 3次无验证判断后,第四次请求会触发验证码验证
- 前端请求获取验证码api,在请求头上带上JWT token
- 后端生成验证码captcha,放到根据JWT token生成一个key,以(key,captcha)存放在中,然后返回图片的base 64编码字符串
- 前端渲染验证码,再次请求手机验证码发送接口,要带上token
- 后端根据前端的token从redis获取captcha,和前端传来的code进行对比,通过之后再进行后续代码
总结
这次联调让我收获最大的就是下面2点:
1. 一定要养成写log的习惯,如果项目已经部署到线上,只能通过log来快速定位bug
2. 善于思考,深入一些原理性的东西,如果对一样东西能理解到原理层面上,就可以更快速找到解决方案














