[导读]当设置为 true 时,示意创立的 Cookie 会被以平安的模式向服务器传输,也就是只能在 HTTPS 连贯中被浏览器传递到服务器端进行会话验证,如果是 HTTP 连贯则不会传递该信息,所以不会被窃取到 Cookie 的具体内容。
一、Cookie 罕用属性
一个 Cookie 蕴含以下信息:
1)Cookie 名称,Cookie 名称必须应用只能用在 URL 中的字符,个别用字母及数字,不能蕴含特殊字符,如有特殊字符想要转码。如 js 操作 cookie 的时候能够应用 escape()对名称转码。
2)Cookie 值,Cookie 值同理 Cookie 的名称,能够进行转码和加密。
3)Expires,过期日期,一个 GMT 格局的工夫,当过了这个日期之后,浏览器就会将这个 Cookie 删除掉,当不设置这个的时候,Cookie 在浏览器敞开后隐没。
4)Path,一个门路,在这个门路上面的页面才能够拜访该 Cookie,个别设为“/”,以示意同一个站点的所有页面都能够拜访这个 Cookie。
5)Domain,子域,指定在该子域下才能够拜访 Cookie,例如要让 Cookie 在 a.test.com 下能够拜访,但在 b.test.com 下不能拜访,则可将 domain 设置成 a.test.com。
6)Secure,安全性,指定 Cookie 是否只能通过 https 协定拜访,个别的 Cookie 应用 HTTP 协定既可拜访,如果设置了 Secure(没有值),则只有当应用 https 协定连贯时 cookie 才能够被页面拜访。
7)HttpOnly,如果在 Cookie 中设置了 ”HttpOnly” 属性,那么通过程序 (JS 脚本、Applet 等) 将无奈读取到 Cookie 信息。
留神: 上图为在 w3shool 上为 setcookie 语法,并没有显示 7 httponly 哦,各自版本反对问题。
一、属性阐明:
1 secure 属性
当设置为 true 时,示意创立的 Cookie 会被以平安的模式向服务器传输,也就是只能在 HTTPS 连贯中被浏览器传递到服务器端进行会话验证,如果是 HTTP 连贯则不会传递该信息,所以不会被窃取到 Cookie 的具体内容。
2 HttpOnly 属性
如果在 Cookie 中设置了 ”HttpOnly” 属性,那么通过程序 (JS 脚本、Applet 等) 将无奈读取到 Cookie 信息,这样能无效的避免 XSS 攻打。
二、各种浏览器查看 cookie 办法
示例:批改《web 攻打之一:XSS 跨站脚本》里的示例一里减少如下红色背景的代码如下:
package com.dxz.web.controller;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletResponse;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
@Controller
public class loginController {@RequestMapping(value="/login",method=RequestMethod.GET)
public ModelAndView helloWorld(@RequestParam("nick") String nick, HttpServletResponse response){System.out.println(nick + "login");
ModelAndView mv = new ModelAndView();
mv.addObject("message", nick);
mv.setViewName("xss2");
Cookie hit=new Cookie("hitCounter","1");
hit.setHttpOnly(true);// 如果设置了 "HttpOnly" 属性,那么通过程序 (JS 脚本、Applet 等) 将无法访问该 Cookie
hit.setMaxAge(60*60);// 设置生存期为 1 小时
//hit.setDomain("www.duanxz.cn");// 子域,在这个子域下才能够拜访该 Cookie
//hit.setPath("/hello");// 在这个门路上面的页面才能够拜访该 Cookie
//hit.setSecure(true);// 如果设置了 Secure,则只有当应用 https 协定连贯时 cookie 才能够被页面拜访
response.addCookie(hit);
return mv;
}
}
再拜访
http://localhost:8080/SpringWebTraining/login?nick=%22%2F%3Cscript%3Ealert%28%22haha%22%29%3C%2Fscript%3E%3C%21-
IE11:
fiddler2:
三、SpringMVC 对 cookie 的操作
cookie 相干阐明:
1、cookie 由服务器端创立,而后增加到 HttpServletResponse 中发送给客户端(浏览器)。
2、能够增加多个 cookie 键值对。
3、cookie 由键值名和键值组成。“雷同 domain 和 path”中的键值名不能反复,增加键值名重名的键值对会笼罩上一个同名的键值对。
4、增加 cookie 时要指定 cookie 所在域(setPath),指定存在时长(setMaxAge)。
4、服务端创立好 cookie 后提交给客户端,之后浏览器的每次申请(HttpServletRequest)里都会携带“cookie 数组”。
5、springmvc 有两种形式获取:(1)在控制器中通过注解 @CookieValue(键值名),获取指定某个 cookie。(2)通过 HttpServletRequest 中的 getcookies 办法获取 cookie 数组,而后迭代外面的每一个 cookie 键值对。
session 相干阐明:
1、服务器会依据客户端的申请(HttpServletRequest)创立 session(request.getSession())。
2、每一个 session 都有一个惟一的标示“sessionID”,可通过.getId()取得。
3、session 是存储在服务器端的,每一个 session 都有一个 id,当创立一个 session 后,会将该 sessionID 寄存到此次拜访的 cookie 中,当下次客户端的拜访到来须要提取服务器中的 session 时,会依据拜访中 cookie 里的 sessionID 值来找到服务器中的具体 session。
4、服务器会把长时间没有流动的 Session 从服务器内存中革除,此时 Session 便生效。Tomcat 中 Session 的默认生效工夫为 20 分钟。
5、拜访 html 等动态资源时不会创立 session
相干操作代码:
// 读取 cookie 数组,之后迭代出各个 cookie
public void showCookies(HttpServletRequest request){Cookie[] cookies = request.getCookies();// 依据申请数据,找到 cookie 数组
if (null==cookies) {// 如果没有 cookie 数组
System.out.println("没有 cookie");
} else {for(Cookie cookie : cookies){System.out.println("cookieName:"+cookie.getName()+",cookieValue:"+ cookie.getValue());
}
}
}
// 创立 cookie,并将新 cookie 增加到“响应对象”response 中。public void addCookie(HttpServletResponse response){Cookie cookie = new Cookie("name_test","value_test");// 创立新 cookie
cookie.setMaxAge(5 * 60);// 设置存在工夫为 5 分钟
cookie.setPath("/");// 设置作用域
response.addCookie(cookie);// 将 cookie 增加到 response 的 cookie 数组中返回给客户端
}
// 批改 cookie,能够依据某个 cookie 的 name 批改它(不只是 name 要与被批改 cookie 统一,path、domain 必须也要与被批改 cookie 统一)public void editCookie(HttpServletRequest request,HttpServletResponse response){Cookie[] cookies = request.getCookies();
if (null==cookies) {System.out.println("没有 cookies");
} else {for(Cookie cookie : cookies){
// 迭代时如果发现与指定 cookieName 雷同的 cookie,就批改相干数据
if(cookie.getName().equals("name_test")){cookie.setValue("new_value");// 批改 value
cookie.setPath("/");
cookie.setMaxAge(10 * 60);// 批改存活工夫
response.addCookie(cookie);// 将批改过的 cookie 存入 response,替换掉旧的同名 cookie
break;
}
}
}
}
// 删除 cookie
public void delCookie(HttpServletRequest request,HttpServletResponse response){Cookie[] cookies = request.getCookies();
if (null==cookies) {System.out.println("没有 cookie");
} else {for(Cookie cookie : cookies){
// 如果找到同名 cookie,就将 value 设置为 null,将存活工夫设置为 0,再替换掉原 cookie,这样就相当于删除了。if(cookie.getName().equals("name_test")){cookie.setValue(null);
cookie.setMaxAge(0);
cookie.setPath("/");
response.addCookie(cookie);
break;
}
}
}
}
附上 js 操作 cookie 的办法:
JS 设置 cookie:
假如在 A 页面中要保留变量 username 的值 (“jack”) 到 cookie 中,key 值为 name,则相应的 JS 代码为:document.cookie="name="+username;
JS 读取 cookie:
假如 cookie 中存储的内容为:name=jack;password=123
则在 B 页面中获取变量 username 的值的 JS 代码如下:
var username=document.cookie.split(";")[0].split("=")[1];
//JS 操作 cookies 办法!
// 写 cookies
function setCookie(name,value)
{
var Days = 30;
var exp = new Date();
exp.setTime(exp.getTime() + Days*24*60*60*1000);
document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();}
读取 cookies
function getCookie(name)
{var arr,reg=new RegExp("(^|)"+name+"=([^;]*)(;|$)");
if(arr=document.cookie.match(reg))
return unescape(arr[2]);
else
return null;
}
删除 cookies
function delCookie(name)
{var exp = new Date();
exp.setTime(exp.getTime() - 1);
var cval=getCookie(name);
if(cval!=null)
document.cookie= name + "="+cval+";expires="+exp.toGMTString();}
// 应用示例
setCookie("name","hayden");
alert(getCookie("name"));
// 如果须要设定自定义过期工夫
// 那么把下面的 setCookie 函数换成上面两个函数就 ok;
// 程序代码
function setCookie(name,value,time)
{var strsec = getsec(time);
var exp = new Date();
exp.setTime(exp.getTime() + strsec*1);
document.cookie = name + "="+ escape (value) + ";expires=" + exp.toGMTString();}
function getsec(str)
{alert(str);
var str1=str.substring(1,str.length)*1;
var str2=str.substring(0,1);
if (str2=="s")
{return str1*1000;}
else if (str2=="h")
{return str1*60*60*1000;}
else if (str2=="d")
{return str1*24*60*60*1000;}
}
// 这是有设定过期工夫的应用示例://s20 是代表 20 秒
// h 是指小时,如 12 小时则是:h12
// d 是天数,30 天则:d30
setCookie("name","hayden","s20");