问题报错:
验证码是存在session中,但是一登录就报验证码失效。
排查步骤:发现是session存的域名不对
1、项目设置的session位置:在拦截器中把验证码存入session
验证码存入session中
@WebServlet("/image/identifyingCode.img")
public class IdentifyingCodeServlet extends HttpServlet {
// 将认证码存入SESSION
session.setAttribute("rand", sRand);
// 图象生效
g.dispose();
ServletOutputStream responseOutputStream = response.getOutputStream();
// 输出图象到页面
ImageIO.write(image, "JPEG", responseOutputStream);
// 以下关闭输入流!
responseOutputStream.flush();
responseOutputStream.close();
}
登录验证验证码
HttpServletRequest request = ContextFilter.context.get();
if (loginType == null || !loginType.equals("auto")) {// 自动登录时不验证验证码
if (request.getSession().getAttribute("rand") == null) {
return getErrorResponse(ResponseCodeEnum.FAIL.getValue(),
getI18n("i18n_account_error_VerificationCodeOverTime", "验证码已过期."));
}
String identifyCode = (String) request.getSession().getAttribute("rand");
if (!identifyCode.equalsIgnoreCase(subAccountVO.getIdentifyCode())) {
return getErrorResponse(ResponseCodeEnum.FAIL.getValue(),
getI18n("i18n_account_error_VerificationCodeError", "验证码错误."));
}
}
域名中配置session的有效位置
Session 默认是不共享的,因为 Cookie 名称为 JSESSIONID 的 Cookie 根域是默认是没设置的,访问不同的二级域名,其 Cookie 就重新生成,而 session 就是根据这个 Cookie 来生成的,所以在不同的二级域名下生成的 Session 也不一样。
解决办法:
在项目的/MET-INF/ 目录下创建一个 context.xml 文件,内容为:
1 2 <?xml version='1.0' encoding='UTF-8'?>
项目中在打包的位置加上content.xml
<?xml version="1.0" encoding="UTF-8"?>
<Context useHttpOnly="true" sessionCookiePath="/"
sessionCookieDomain=".wingtech.com" />
拓展1:
cookie 常见属性
(1)name=value
键值对,设置 Cookie 的名称及相对应的值。
(2)domain
指定 cookie 所属域名,默认是当前域名。如果 cookie 的 domain 设置为 taobao.com,那么 item.taobao.com, order.taobao.com 都是可以共享 cookie 的, 但是访问 tmall.com 就不能共享 cookie 了,这就涉及跨域访问的问题,跨域问题如何解决,这里不展开,有兴趣可以自行搜索。
(3)path
指定 cookie 在哪个路径(路由)下生效,默认是 '/'。如果设置为 /abc,则只有 /abc 下的路由可以访问到该 cookie,如:/abc/read。
(4)expires
指定 cookie 的过期时间(GMT时间格式),到达该时间点后该 cookie 就会自动失效。
(5)max-age
HTTP 1.1中定义的,优先级高于 expires 字段。
max-age 表示 cookie 有效期,单位秒。如果为正数,则该 cookie 在 max-age 秒后失效;如果为负数,该 cookie 为临时 cookie ,关闭浏览器即失效,浏览器也不会以任何形式保存该 cookie ;如果为 0,表示删除该 cookie 。默认为 -1。
(6)HttpOnly
如果给某个 cookie 设置了 httpOnly 属性,则无法通过 JS 脚本读写该 cookie 的信息。
(7)secure
该 cookie 是否仅被使用安全协议传输,默认为false。当 secure 值为 true 时,cookie 在 HTTP 中是无效的
拓展2:@Webserverlet注解用法
在servlet3.0以后,我们可以不用再web.xml里面配置servlet,只需要加上@WebServlet注解就可以修改该servlet的属性了。
下面是@WebServlet的属性列表。
属性名 类型 描述
name String 指定Servlet 的 name 属性,等价于 <servlet-name>。如果没有显式指定,则该 Servlet 的取值即为类的全限定名。
value String[] 该属性等价于 urlPatterns 属性。两个属性不能同时使用。
urlPatterns String[] 指定一组 Servlet 的 URL 匹配模式。等价于<url-pattern>标签。
loadOnStartup int 指定 Servlet 的加载顺序,等价于 <load-on-startup>标签。
initParams WebInitParam[] 指定一组 Servlet 初始化参数,等价于<init-param>标签。
asyncSupported boolean 声明 Servlet 是否支持异步操作模式,等价于<async-supported> 标签。
description String 该 Servlet 的描述信息,等价于 <description>标签。
displayName String 该 Servlet 的显示名,通常配合工具使用,等价于 <display-name>标签。