有关cookie的介绍:http://blog.youkuaiyun.com/xiaobaoxiaodun/article/details/6896749
在一个项目中,Cookie属于项目级的资源,应该统一进行管理,即在一个项目中应该指定专人进行cookie的写操作,其他人通过提供的方法进行读操作。这个在项目开发初始就应当约定好,不应当出现随意的写操作,这是造成混乱的根源。
大概问了下几个同事,关于cookie的基础知识,大家都知道,容易混淆的大概有这么两个问题:
1、命名空间的问题
通过cookie.setDomain(“”)可以设置该cookie的命名空间或者说是访问级别,比如,我们在price.yxd.com这个项目中调用cookie.setDomain(“yxd.com”)的时候,就为该cookie设置了一个2级域名的访问级别,这样的话,我们在union.yxd.com这个域名下,是可以访问刚才在price.yxd.com中的cookie的,如果在程序中不做setDomain的操作,这个cookie是放到3级域名下的,即price.yxd.com下的,在这种情况下,union.yxd.com就访问不到price.yxd.com中的cookie了。
总结如下:
3级域名可以访问2级域名的cookie,比如,union.yxd.com可以访问yxd.com里的cookie,但是反过来是不可以的。有点像java的继承关系,子类可以访问父类的东西,但是父类不能访问子类的东西,子类和子类之间也不能互相访问。
在开发中,如果一个项目和别的项目之间没有什么域名上的交互,那么在本项目内对cookie的使用其实也没什么讲究;如果项目之间需要通过cookie来进行交互的,那么一定要约定好domain的设置了。
2、 Cookie的安全问题
采用servet3.0的标准,用cookie.setHttpOnly(true)的方式,可以不让javascript这种客户端脚本读到当前域下的cookie,这在一定程度上避免了cookie的过分暴漏;但是按照cookie的规范,它只是一段文本而已,所以在浏览器里不管怎样都可以看到某个站点的cookie。
针对安全问题,在使用的时候有几点要注意:
1、 不要在cookie中存放敏感信息,比如存折账户、密码什么的,如果一定要存,可采用加密的方式。
2、 可以采用这种方式来存储信息:key=123456|yxd|1,而不是id=123456,name=yxd,isadmin=1的方式。在服务器端再进行信息的拆分。
3、 谨记cookie的设计初衷,绝不是提供保存大量数据的,所以我们使用的时候应该顺着用,而不能逆着用。事实上在新的html5规范里,针对cookie的这些缺陷,已经提出了本地存储的概念,但这些还需要时间。
项目开发中好的实践:
将cookie中要存储的信息统一包装成数据对象,由工具类对外提供统一的读取方法,这样,在其他程序看来,并不是在读取cookie,而只是通过工具获得自己需要的信息而已:如下:
第一步:封装cookie中要存储的信息为POJO
public class CookieObject {
private long userId;
private long partnerId;
private String auth;
private boolean isPrimary;
public CookieObject(long userId, long partnerId, String auth,boolean isPrimary) {
this.userId = userId;
this.partnerId = partnerId;
this.auth = auth;
this.isPrimary = isPrimary;
}
省略getters and setters
第二步:封装获取cookieObject的方法:
/**
* 获取cookie值
* @return
*/
public static CookieObject getCookie(BeatContext beat){
Cookie[] cookies=beat.getRequest().getCookies();
Cookie cookie=null;
for(int i=0;i<cookies.length;i++){
cookie=cookies[i];
if(Constant.COOKIE_KEY.equals(cookie.getName())){
String[] cookieNms=cookie.getValue().split(Constant.COOKIE_SPLIT);
return new CookieObject(Long.parseLong(cookieNms[0]),
Long.parseLong(cookieNms[1]),
cookieNms[2],
"1".equals(cookieNms[3])?true:false);
}
}
return null;
}
这样就将cookie的信息转换为一个普通的数据对象,同时也对cookie的读写操作进行了控制。
还有一些项目中不好的例子,就不再一一列举了,跑不出上面的两点。