今天,测试大兄弟发来消息说线上一直提示验证码错误,测试环境没有这情况。收到问题自然要去排查了,由于代码不是我撸的,只能去看代码怎么实现的了。通过查看代码大致实现就是把验证码的值保存到session中,然后输出一个图片流。按照之前jsp之类的套路好像确实也没啥问题。但是我们做了前后端分离,后台也许也会部署多台机器,如果没有做session共享这就凉凉了吧。当然通过spring-session-data-redis 可以轻松实现,但是大多都是接口,令牌鉴权完全够了,为了一个验证码完全没必要。有没有什么其他方式呢?答案是必须有,uuid + base64 + redis 就可以满足。

     生产验证码时,将随机字符串保存到redis key 为uuid ,值为随机字符串。然后给前端返回uuid + 验证码base64字符串即可。提交表单,把uuid 跟输入的验证码一起传回来即可,后台从redis 获取对比。

     这么一改,肯定是满足我们项目的。但是我存在一个疑问,因为我们线上目前是单机,测试环境没问题。那肯定有其他原因,导致验证码不正确。查看日志打印出session中的验证码是null,why?session 丢了?仔细想了下,原来测试环境跟生产部署方式还有点区别。测试环境页面跟接口在一个域名下,生产则是两个域名。会不会是跨域之后会话没了?目前猜测是,找了下相关资料,还真有跨域导致的。

    

跨域注意
1.前端ajax访问时要加上“xhrFields: {withCredentials: true}” ,实现session可以传递; 
2.配置拦截器,response.setHeader(“Access-Control-Allow-Origin”, “*”),实现跨域访问问题; 
3.配置拦截器,response.addHeader(“Access-Control-Allow-Credentials”, “true”),实现session传值问题;* 
4.配置拦截器,如果配置了Access-Control-Allow-Credentials=true,则跨域拦截Access-Control-Allow-Origin 必须是指定的url,response.setHeader(“Access-Control-Allow-Origin”, url);

考虑到以后还是会增加机器,还是改成uuid + base64 + redis方式比较符合。mark