修改cookie java_Java之道丨Cookie 防伪造 防修改-cookies设置

本文介绍了Cookie的基础知识,包括其用途、限制和管理。详细讲解了如何在Java中创建、读取、删除Cookie,以及如何防止Cookie被伪造和修改。通过示例代码展示了如何保存复杂对象和实现安全的Cookie存储机制。
摘要由CSDN通过智能技术生成

49a87970ad8598bde5c4f850b7e2a297.png

Cookie 概述

Cookie是什么? Cookie 是一小段文本信息,伴随着用户请求和页面在 Web 服务器和浏览器之间传递。Cookie 包含每次用户访问站点时 Web 应用程序都可以读取的信息。

为什么需要Cookie? 因为HTTP协议是无状态的,对于一个浏览器发出的多次请求,WEB服务器无法区分是不是来源于同一个浏览器。所以,需要额外的数据用于维护会话。Cookie 正是这样的一段随HTTP请求一起被传递的额外数据。

Cookie能做什么? Cookie只是一段文本,所以它只能保存字符串。而且浏览器对它有大小限制以及它会随着每次请求被发送到服务器,所以应该保证它不要太大。Cookie的内容也是明文保存的,有些浏览器提供界面修改,所以,不适合保存重要的或者涉及隐私的内容。

Cookie 的限制。 大多数浏览器支持最大为 4096 字节的 Cookie。由于这限制了 Cookie 的大小,最好用 Cookie 来存储少量数据,或者存储用户 ID 之类的标识符。用户 ID 随后便可用于标识用户,以及从数据库或其他数据源中读取用户信息。浏览器还限制站点可以在用户计算机上存储的 Cookie 的数量。大多数浏览器只允许每个站点存储 20 个 Cookie;如果试图存储更多 Cookie,则最旧的 Cookie 便会被丢弃。有些浏览器还会对它们将接受的来自所有站点的 Cookie 总数作出绝对限制,通常为 300 个。

通过前面的内容,我们了解到Cookie是用于维持服务端会话状态的,通常由服务端写入,在后续请求中,供服务端读取。下面本文将按这个过程看看Cookie是如何从服务端写入,最后如何传到服务端以及如何读取的。

Cookie的写、读过程//把对象存入cookie中

Cookie cookieName=new Cookie("loginname", loginname);

Cookie cookiePassword=new Cookie("loginpassword", loginpassword);

cookieName.setPath(request.getContextPath());

cookiePassword.setPath(request.getContextPath());

cookieName.setMaxAge(60*60);//只保存一分钟

cookiePassword.setMaxAge(60*60);//只保存一分钟

response.addCookie(cookieName);

response.addCookie(cookiePassword);

//获取浏览器访问访问服务器时传递过来的cookie数组

Cookie[] cookies = request.getCookies();

//如果用户是第一次访问,那么得到的cookies将是null

if (cookies!=null) {

out.write("您上次访问的时间是:");

for (int i = 0; i < cookies.length; i++) {

Cookie cookie = cookies[i];

if (cookie.getName().equals("lastAccessTime")) {

Long lastAccessTime =Long.parseLong(cookie.getValue());

Date date = new Date(lastAccessTime);

out.write(date.toLocaleString());

}

}

}else {

out.write("这是您第一次访问本站!");

}

//用户访问过之后重新设置用户的访问时间,存储到cookie中,然后发送到客户端浏览器

Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");//创建一个cookie,cookie的名字是lastAccessTime

//将cookie对象添加到response对象中,这样服务器在输出response对象中的内容时就会把cookie也输出到客户端浏览器

response.addCookie(cookie);

7e14fd91928481d28e0d7c005cc75b18.png

Cookie

从上图,您应该能发现,我们在服务端写的Cookie,最后其实是通过HTTP的响应头这种途径发送到客户端的。每一个写入动作,都会产生一个【Set-Cookie】的响应头。

浏览器正是在每次获取请求的响应后,检查这些头来接收Cookie的。

从图片中发现,Cookie是放在请求头中,发送到服务端的。如果你一直刷新页面,就能发现,每次HTTP请求,Cookie都会被发送。当然了,浏览器也不是发送它所接收到的所有Cookie,它会检查当前要请求的域名以及目录,只要这二项目与Cookie对应的Domain和Path匹配,才会发送。对于Domain则是按照尾部匹配的原则进行的。所以,我在访问 www.cnblogs.com 时,浏览器并不会将我在浏览 www.163.com 所接收到的 Cookie 发出去。

删除Cookie:其实就是在写Cookie时,设置Expires为一个【早于现在时间的时间】。也就是:设置此Cookie已经过期,浏览器接收到这个Cookie时,便会删除它们。//创建一个名字为lastAccessTime的cookie

Cookie cookie = new Cookie("lastAccessTime", System.currentTimeMillis()+"");

//将cookie的有效期设置为0,命令浏览器删除该cookie

cookie.setMaxAge(0);

response.addCookie(cookie);

//清除cookie

Cookie cookies[] = request.getCookies();

if (cookies != null)

{

for (int i = 0; i < cookies.length; i++)

//清空cookie值“”

cookies[i].setValue("");

//设置有限时间为0

cookies[i].setMaxAge(0);

//添加有效时间为0的cookie

response.addCookie(cookies[i]);

//Cookie cookieName = new Cookie("loginname","");//这边得用"",不能用null

// Cookie cookiePassword = new Cookie("loginpassword","");//这边得用"",不能用null

// cookieName.setPath(request.getContextPath());//设置成跟写入cookies一样的

// cookiePassword.setPath(request.getContextPath());//设置成跟写入cookies一样的

// cookie.setDomain(".wangwz.com");//设置成跟写入cookies一样的

// cookieName.setMaxAge(0);

// cookiePassword.setMaxAge(0);

// response.addCookie(cookieName);

//response.addCookie(cookiePassword);

}

// 把对象存入session中

request.getSession().setAttribute("org_Employee", org_Employee);

response.sendRedirect("xx");

使用Cookie保存复杂对象

前面的示例代码大致演示了Cookie的读写操作。不过,我们平时可能希望将更复杂的【自定义类型】通过Cookie来保存,那么又该如何操作呢?对于这个问题,我们定义一个类型来看看如何处理。public class DisplaySettings {

public int Style;

public int Size;

public override string ToString() {

return string.Format("Style = {0}, Size = {1}", this.Style, this.Size);

}

}

将对象序列化成Json串:

public static string ObjectToJson(object obj)

{

return Newtonsoft.Json.JsonConvert.SerializeObject(obj);

}

将Json串反序列化成对象:

public static object JsonToObject(string jsonString)

{

return Newtonsoft.Json.JsonConvert.DeserializeObject(jsonString);

}

传统cookie存储,Cookie(name, value),value很容易就被篡改。

防修改cookie存储,Cookie(name, value+“&&”+ signToken+“&&”+saveTime+“&&”+maxTime)

signToken :签名密钥 由md5(value+saveTime+maxTime+”自定义密钥“)生成

saveTime:cookie创建时间

maxTime:cookie超时时间

设置Cookiepublic static void put(HttpServletResponse response, String key, String value, int maxTime) {

String pwdKey = "white_yu"; //自定义密钥

String saveTime = System.currentTimeMillis() + "";

String signToken = md5(pwdKey, saveTime, maxTime + "", value);

String cookieValue = signToken + "&&" + saveTime + "&&" + maxTime

+ "&&" + value;

Cookie cookie = new Cookie(key,cookieValue);

cookie.setMaxAge(maxTime);

response.addCookie(cookie);

}

获取Cookiepublic static String getCookie(String cookieValue) {

String pwdKey = "white_yu"; //自定义密钥

if (StringUtils.isNotBlank(cookieValue)) {

String cookieStrings[] = cookieValue.split("&&");

if (null != cookieStrings && 4 == cookieStrings.length) {

String signToken = cookieStrings[0];

String saveTime = cookieStrings[1];

String maxTime = cookieStrings[2];

String value = cookieStrings[3];

String sign = md5(pwdKey, saveTime, maxTime, value);

// 保证 cookie 不被人为修改

if (sign.equals(signToken)) {

long stime = Long.parseLong(saveTime);

long maxtime = Long.parseLong(maxTime) * 1000;

// 查看是否过时

if ((stime + maxtime) - System.currentTimeMillis() > 0) {

return value;

}

}

}

}

return null;

}

Cookie注意细节一个Cookie只能标识一种信息,它至少含有一个标识该信息的名称(NAME)和设置值(VALUE)。

一个WEB站点可以给一个WEB浏览器发送多个Cookie,一个WEB浏览器也可以存储多个WEB站点提供的Cookie。

浏览器一般只允许存放300个Cookie,每个站点最多存放20个Cookie,每个Cookie的大小限制为4KB。

如果创建了一个cookie,并将他发送到浏览器,默认情况下它是一个会话级别的cookie(即存储在浏览器的内存中),用户退出浏览器之后即被删除。若希望浏览器将该cookie存储在磁盘上,则需要使用maxAge,并给出一个以秒为单位的时间。将最大时效设为0则是命令浏览器删除该cookie。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值