环境:前后端分离,部署在同一台服务器上
问题:前端登录页面实现验证码功能,使用的是catpcha框架,在web.xml中配置,但是在验证码验证中获取不到captcha在session的值,显示为null。
过程:
1、导入maven坐标
<dependency> <groupId>com.github.penggle</groupId> <artifactId>kaptcha</artifactId> <version>2.3.2</version> <exclusions> <exclusion> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> </exclusion> </exclusions> </dependency>
2、web.xml 配置Servlet
<servlet> <servlet-name>cap</servlet-name> <servlet-class>com.google.code.kaptcha.servlet.KaptchaServlet</servlet-class> <init-param> <param-name>kaptcha.border</param-name> <param-value>no</param-value> </init-param> <init-param> <param-name>kaptcha.textproducer.char.length</param-name> <param-value>4</param-value> </init-param> <init-param> <param-name>kaptcha.textproducer.char.string</param-name> <param-value>abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789</param-value> </init-param> <init-param> <param-name>kaptcha.background.clear.to</param-name> <param-value>211,229,237</param-value> </init-param> <init-param> <!-- session.setAttribute("captcha","验证码") --> <param-name>kaptcha.session.key</param-name> <param-value>captcha</param-value> </init-param> </servlet> <servlet-mapping> <servlet-name>cap</servlet-name> <!-- 请求如下地址,就能获取一个验证码图片 --> <url-pattern>/captcha</url-pattern> </servlet-mapping>
3、vue登录页面
4、后端代码
String kaptchaExpected = (String)request.getSession().getAttribute(com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY); System.out.println("session中获取的验证码:"+kaptchaExpected); String kaptchaReceived = request.getParameter("code"); System.out.println("前端提交的验证码:"+kaptchaReceived);
4、登录请求
5、打印输出
解决办法:
最后发现是获取session的键值对写错了,把
com.google.code.kaptcha.Constants.KAPTCHA_SESSION_KEY改为setAttribute对应的key,我的是web.xml中帮我创建放到session中了,键值对为captcha。
如果没在web.xml中配置,则要自己手动创建,参考这篇文章:http://t.csdn.cn/iCgqu
成功获取
总结:
1、前后端都没有配置// axios.defaults.withCredentials=true//
allow-credentials="true"
允许跨域时携带cookie,但是仍然可以访问到session中的值,说明是不是使用的同一个session,这个我还没有验证,有大佬可以验证一下。
2、验证码得刷新session中才能获取,如果保持旧的验证码获取session为空。
3、如果没有配置setAttribute放到session中,则getAttribute后面就填我上面过程第4步的代码,自己没有设置键值对,就用谷歌默认的键值对,也能获取到session中的值。
4、写得不好大佬多多指出,我不懂的还有好多好多。
参考文章: 基于ssm实现验证码功能 - 默小希 - 博客园 (cnblogs.com)