public void intercept(Invocation ai) {
// TODO Auto-generated method stub
HttpSession session = ai.getController().getSession();
//判断session是否为空
if(session == null){
ai.getController().redirect("/login?systype="+ai.getControllerKey());
}
else{
//判断session中的用户是否还存在
String userAccount = (String) session.getAttribute("userAccount");
String userName = (String) session.getAttribute("userName");
if(userName != null&&userAccount !=null) {
ai.getController().redirect("/"+ai.getMethod().getName());
ai.invoke();
}
else {
ai.getController().redirect("/login?systype="+ai.getControllerKey());
}
}
}
public void handle(String target, HttpServletRequest request,HttpServletResponse response, boolean[] isHandled) {
Cookie[] cookies = request.getCookies();
//对cookie进行了处理
if(cookies!=null){
for(Cookie cookie : cookies){
String value = cookie.getValue();
StringBuilder builder = new StringBuilder();
builder.append("JSESSIONID=" + value + "; ");
builder.append("Secure; ");
builder.append("HttpOnly; ");
Calendar cal = Calendar.getInstance();
cal.add(Calendar.HOUR, 1);
Date date = cal.getTime();
Locale locale = Locale.CHINA;
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss",locale);
builder.append("Expires=" + sdf.format(date));
response.setHeader("Set-Cookie", builder.toString());
}
}
String ctx = WebContextUtil.getContextPath(request);
String referer=request.getHeader("Referer");
if(StrKit.notBlank(referer) && !referer.contains(ctx)){
response.setContentType("text/html;charset=GBK");
response.setCharacterEncoding("GBK");
response.setStatus(403);
try {
response.getWriter().print("对不起,您的请求非法,系统拒绝响应!");
} catch (IOException e) {
e.printStackTrace();
}
return;
}else{
String method = request.getMethod();
if(!"GET".equals(method)&&!"POST".equals(method)&&!"HEAD".equals(method)){
response.setContentType("text/html;charset=GBK");
response.setCharacterEncoding("GBK");
response.setStatus(403);
try {
response.getWriter().print("对不起,您的请求非法,系统拒绝响应!");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return;
}else{
if (target.indexOf(".") == -1&&!target.contains("manager")){
request = new HttpServletRequestWrapper(request);
}
next.handle(target, request, response, isHandled);
}
}
}
一个域名下面可能存在着很多个cookie对象。
name字段为一个cookie的名称。
value字段为一个cookie的值。
domain字段为可以访问此cookie的域名。
非顶级域名,如二级域名或者三级域名,设置的cookie的domain只能为顶级域名或者二级域名或者三级域名本身,不能设置其他二级域名的cookie,否则cookie无法生成。
顶级域名只能设置domain为顶级域名,不能设置为二级域名或者三级域名,否则cookie无法生成。
二级域名能读取设置了domain为顶级域名或者自身的cookie,不能读取其他二级域名domain的cookie。所以要想cookie在多个二级域名中共享,需要设置domain为顶级域名,这样就可以在所有二级域名里面或者到这个cookie的值了。
顶级域名只能获取到domain设置为顶级域名的cookie,其他domain设置为二级域名的无法获取。
path字段为可以访问此cookie的页面路径。 比如domain是abc.com,path是/test,那么只有/test路径下的页面可以读取此cookie。
expires/Max-Age 字段为此cookie超时时间。若设置其值为一个时间,那么当到达此时间后,此cookie失效。不设置的话默认值是Session,意思是cookie会和session一起失效。当浏览器关闭(不是浏览器标签页,而是整个浏览器) 后,此cookie失效。
Size字段 此cookie大小。
http字段 cookie的httponly属性。若此属性为true,则只有在http请求头中会带有此cookie的信息,而不能通过document.cookie来访问此cookie。
secure 字段 设置是否只能通过https来传递此条cookie
Cookie的Secure属性
基于安全的考虑,需要给cookie加上Secure和HttpOnly属性,HttpOnly比较好理解,设置HttpOnly=true的cookie不能被js获取到,无法用document.cookie打出cookie的内容。
Secure属性是说如果一个cookie被设置了Secure=true,那么这个cookie只能用https协议发送给服务器,用http协议是不发送的。换句话说,cookie是在https的情况下创建的,而且他的Secure=true,那么之后你一直用https访问其他的页面(比如登录之后点击其他子页面),cookie会被发送到服务器,你无需重新登录就可以跳转到其他页面。但是如果这是你把url改成http协议访问其他页面,你就需要重新登录了,因为这个cookie不能在http协议中发送。
例子是:
前提条件:https://localhost:9102应用对cookie设置了Secure=true
1. 访问 https://localhost:9102/manager
2. 输入用户名、密码,用IE或者Chrome的developer tool会看到response的header里,set-cookie的值里有Secure属性
3. 登录后,继续访问https://localhost:9102/manager#user,可以正常看到内容
4. 修改url,访问http://localhost:9100/manager#domain,会跳转到登录页面,因为cookie在http协议下不发送给服务器,服务器要求用户重新登录
在工作当中遇到了360浏览器兼容性问题。当使用XssHandler将Cookie设置成只支持HTTPS协议时,会导致后台接收请求时接收不到Cookie从而找不到session,导致tiao'跳出登陆系统。其他浏览器(chrome,原生IE)并未出现此情况。
后调查发现,因为JFINAL框架,前台调用后台Controller时,直接写路径不制定具体方法,虽然会默认制定到该Controller下的index方法。而当改变cookie支持协议后,继续使用这种默认方式,会使360l浏览器发送请求时不携带cookie,所以要将1路径改为/controllerName/index使用。