Cookie用法详细介绍

cookie简介

1. 定义

cookie是由服务器发送给客户端(浏览器)的小量信息。

2. 作用

cookie是键值对形式存储的少量信息,那它有什么作用呢?

我们知道,平时上网时都是使用无状态的HTTP协议传输出数据,这意味着客户端与服务端在数据传送完成后就会中断连接。这时我们就需要一个一直保持会话连接的机制。在session出现前,cookie就完全充当了这种角色。也就是,cookie的小量信息能帮助我们跟踪会话。一般该信息记录用户身份。

当然cookie也常记录跟踪购物车的商品信息(如数量)、记录用户访问次数等。

3. 原理

客户端请求服务器时,如果服务器需要记录该用户状态,就使用response向客户端浏览器颁发一个Cookie。而客户端浏览器会把Cookie保存起来。当浏览器再请求服务器时,浏览器把请求的网址连同该Cookie一同提交给服务器。服务器通过检查该Cookie来获取用户状态。

4.添加cookie示例

获取客户端的Cookie时,只能获取name与value属性,其它属性都不会被提交。

    Cookie c = new Cookie("username","peter");// 新建一个Cookie对象
    c.setMaxAge(24*60*60);                    // 设置过期时间1天,以秒为单位
    response.addCookie(c);                    // 保存cookie到客户端

5.删除cookie示例

删除某个Cookie时,只需要新建一个只有maxAge和value不一样的同名Cookie,然后添加到response中覆盖原来的Cookie

    Cookie cookie = new Cookie("username","peter");// 新建Cookie
    cookie.setMaxAge(0);                           // 设置生命周期为0,表示将要删除
    response.addCookie(cookie);                    // 执行添加后就从response里删除了

6.修改cookie示例

修改某个Cookie时,只需要新建一个只有value属性不一样的同名Cookie,然后添加到response中覆盖原来的Cookie

    Cookie cookie = new Cookie("username","joker");// 新建Cookie
    cookie.setMaxAge(24*60*60);                    // 设置生命周期
    response.addCookie(cookie);                    // 执行添加后就从response里覆盖修改了

注意:修改、删除Cookie时,新建的Cookie除value、maxAge之外的所有属性,例如name、path、domain等,都要与原Cookie完全一样。否则,浏览器将视为两个不同的Cookie而不会覆盖之前的Cookie,从而导致修改、删除失败。

Cookie类的各方法详解

Cookie类在javax.servlet.http.Cookie包中

对应的getter方法我就不讲了。

如果cookie值为Unicode字符,需要为字符编码。如果cookie值为二进制数据,则需要使用BASE64编码

cookie的setPath()和setDomain()方法

默认情况下cookie只能在一个应用中共享,即一个cookie只能由创建它的应用获得。

设置同一服务器内的cookie使用范围用setPath

c.setPath(“/”),使同一服务器内所有应用都可访问到该Cookie:

    Cookie c = new Cookie("name","peter");
    c.setMaxAge(24*60*60);  
    c.setPath("/");//同一服务器内所有应用都可访问到该Cookie
    response.addCookie(c); //保存cookie到客户端

1.如果同一服务器内有两个应用agx1.0和agx2.0

当我们在agx1.0里有c.setPath(“/agx2.0/”);时,该cookie就只能在agx2.0下面能获取到,就连创建该cookie的agx1.0也获取不到。

2.如果在agx1.0里有c.setPath(“/agx2.0/abc/”);时,则只能在agx2.0/abc下面才能获得该cookie,即使在agx2.0下面也不能获取到。

cookie的跨域

1.正常情况下Cookie不可跨域名,如域名www.google.com颁发的Cookie不会被提交到域名www.baidu.com去。这是由Cookie的隐私安全机制决定的。即使在同一个一级域名下的两个二级域名如www.agx.comimages.agx.com也不能交互使用Cookie,因为二者的域名并不严格相同。如果想所有agx.com名下的二级域名都可以使用该Cookie,则需要设置Cookie的domain参数为”.agx.com”,例如:

    Cookie cookie = new Cookie("name","peter"); // 新建Cookie
    cookie.setDomain(".agx.com");               // 设置域名
    cookie.setPath("/");                        // 设置路径
    cookie.setMaxAge(Integer.MAX_VALUE);        // 设置有效期为永久
    response.addCookie(cookie);                 // 输出到客户端

读者可以修改本机C:\WINDOWS\system32\drivers\etc下的hosts文件来配置多个临时域名,然后使用setCookie.jsp程序来设置跨域名Cookie验证domain属性。

注意:domain参数必须以点(“.”)开始。另外,name相同但domain不同的两个Cookie是两个不同的Cookie。如果想要两个域名完全不同的网站共有Cookie,可以生成两个name相同的Cookie,domain属性分别为两个域名。

2.若A服务器的域名为:adv.audiogroup.com,有应用名为:agx1.0; B服务器的域名为:agx.com,有应用名为:agx2.0。

在A服务器的agx1.0应用下设置cookie如下:

    Cookie cookie = new Cookie("name","peter"); // 新建Cookie
    cookie.setDomain(".agx.com");               // 设置域名
    cookie.setPath("/");                        // 设置路径
    cookie.setMaxAge(Integer.MAX_VALUE);        // 设置有效期为永久
    response.addCookie(cookie);                 // 输出到客户端

这时,在B服务器下的agx2.0应用和agx1.0里都能取到上面的Cookie。

注:输入URL访问agx2.0时,必须输入域名才能获取其它服务器共享给它的cookie,如:

输入http://images.agx.com:8080/agx2.0,可以获取agx1.0在客户端设置的cookie

输入:http://localhost:8080/agx2.0则不可以获得cookie。

setPath()与setDomain()的区别?

setDomain()主要用来确定两个不同名称但后缀相同的网站地址是否能使用同一个Cookie。

例: www.agx.combbs.agx.com只要有cookie.setDomain(“.zjut.edu.cn”);就都能使用该cookie

setPath()主要用来确定地址里什么后缀下能够使用这个Cookie

归结起来就是:setDomain决定允许访问Cookie的域名,而setPath决定允许访问Cookie的路径(ContextPath)

获取用户请求里的cookie

    Cookie[] cookie = request.getCookies();//获取的是请求里的所有cookie组成的数组
    for(int i=0;i<cookie.length;i++){
        if("name".equals(cookie[i].getName())){
            System.out.println(cookie[i].getValue());//得到peter
            break;
        }
    }

解决cookie里中文乱码问题

Cookie中要保存中文只能编码。一般使用UTF-8编码即可。不推荐使用GBK等中文编码,因为浏览器不一定支持,而且JavaScript也不支持GBK编码。

Cookie不仅可以使用ASCII字符与Unicode字符,还可以使用二进制数据。例如在Cookie中使用数字证书,提供安全度。使用二进制数据时也需要进行编码(如用BASE64编码保存二进制图片)。由于浏览器每次请求都会带着Cookie,因此Cookie内容不宜过多,所以一般不会在Cookie中存储二进制的内容

JS操作Cookie

Cookie是保存在客户端的,所以浏览器可以使用脚本(JS)等操作Cookie。

<script language=javascript> 
    //添加cookie
    function setCookie(name,value,time){ 
        var date= new Date(); 
        date.setDate(date.getDate()+time); 
        document.cookie = name+"="+value+";expires="+date; 
    } 
 
    //获得cookie
    function getCookie(name){ 
        var arr = document.cookie.split(";"); 
        for(var i=0; i<arr.length; i++){ 
        var arr2 = arr[i].split("="); 
            if(arr2[0] == name){ 
                return arr2[1]; 
            } 
        } 
        return null; 
    } 
 
    //删除cookie
    function removeCookie(name){ 
        setCookie(name,"",0) 
    } 
</script>

W3C标准的浏览器会阻止JavaScript读写任何不属于自己网站的Cookie。即A网站的JavaScript代码里获取不到B网站的Cookie。

使用cookie记住密码

方案1:

直接把用户名与密码都保持到Cookie中,下次访问时检查Cookie中的用户名与密码,与数据库比较。这是一种比较危险的选择,一般不把密码等重要信息保存到Cookie中。

方案2:

把密码加密后保存到Cookie中,下次访问时解密并与数据库比较。这种方案略微安全一些。如果不希望保存密码,还可以把登录的时间戳保存到Cookie与数据库中,到时只验证用户名与登录时间戳就可以了。

方案3:

实现方式是把账号按照一定的规则(密钥)加密后,连同账号一块保存到Cookie中。下次访问时只需要判断账号的加密规则是否相同即可。

加 密:

    String userName = request.getParameter("userName");//获取用户名
    Md5Hash psw = new Md5Hash(userName, "peter.com", 2);//以peter.com为密钥加密
 
    //将用户名添加进cookie并发送给客户端
    Cookie userCookie = new Cookie("userName",userName);
    userCookie.setMaxAge(7*24*60*60);
    response.addCookie(userCookie);
    
    //将密钥生成的密文加进cookie并发送给客户端
    Cookie c = new Cookie("key",psw.toString());
    c.setMaxAge(7*24*60*60);
    response.addCookie(c);

解密:

    String usreName = null;
    String key = null;
    Cookie[] cookie = request.getCookies();
    if(cookie !=null){              
        for(Cookie c:cookie){  // 遍历Cookie
           if("userName".equals(c.getName()) 
               userName = c.getValue();      
           if("key".equals(c.getName()) 
               key= cookie.getValue();       
        }
    }
    if(userName != null && key != null){   
        String secrect = new Md5Hash(userName, "peter.com", 2);
        if(key.equals(secrect )){//加密规则正确,说明已经登录
            //...
            //....省略后续处理
        }
    }

由上面可知,如果将密码加密后存进cookie后,当我们下次访问登录页时,密码框里的密码将不是用户真正的密码。

原文链接:https://blog.csdn.net/qq_29132907/article/details/80390792

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Session、Cookie、Token、JWT都是在Web开发中用于管理用户身份认证和会话管理的工具。 1. Session:Session指的是服务器端保存的用户信息。当用户登录成功后,服务器会创建一个session,为该用户分配一个session ID,并将该ID保存到cookie中,发送给客户端。客户端浏览器保存了这个cookie,以后每次请求都会带上这个cookie,服务器通过这个cookie就可以识别出用户身份,从而进行相应的操作。Session机制存在一定的风险,比如会话劫持、会话固定等问题,需要注意安全性。 2. CookieCookie是一种客户端保存用户信息的机制,它是由服务器在响应HTTP请求时通过Set-Cookie头部字段发给客户端浏览器的一小段文本信息。浏览器将这些信息保存在客户端,以后每次向服务器发送请求时都会自动带上这些cookie,从而实现身份认证和会话管理。但是Cookie也存在一些安全问题,比如会话劫持、跨站脚本攻击等问题。 3. Token:Token是一种用户身份认证和授权的机制,通常由服务器生成,以便在客户端和服务端之间进行身份认证和授权。客户端在登录成功后,服务器会为该用户生成一个Token,并将Token发送给客户端浏览器。客户端在之后的请求中需要携带该Token,服务器验证Token的有效性后,就可以识别出用户身份,并进行相应的操作。Token相比Session和Cookie,具有更高的安全性和可扩展性。 4. JWT:JWT是一种基于Token的身份认证和授权机制。JWT包含三部分,分别是头部、载荷和签名。头部包含加密算法和类型等信息;载荷包含用户的身份信息和相关的元数据等信息;签名则是对头部和载荷进行签名生成的一段密文,用于验证Token的有效性。JWT具有无状态、可扩展、跨域等特点,被广泛用于Web开发中的用户身份认证和授权。 ### 回答2: Session、Cookie、Token和JWT都是常见的身份验证和会话管理方法。下面我会分别介绍它们。 Session:Session是服务器端记录用户状态的一种机制。当用户通过用户名和密码登录后,服务器会为该用户创建一个唯一的Session。之后,用户再发送请求时,服务器会根据Session来识别用户并获取用户的状态信息。 CookieCookie是一种在客户端存储的小型文本文件。在用户通过用户名和密码登录成功后,服务器可以将一个包含Session信息的Cookie发送给客户端,客户端会将该Cookie保存下来。之后,客户端发送请求时,会自动附带上该Cookie,用于向服务器证明用户的身份。 Token:Token是一种代表用户身份的令牌。与Cookie不同,Token是在客户端保存的,并且不需要服务器端存储用户状态。当用户登录成功后,服务器会生成一个Token并发送给客户端,客户端将其保存起来。之后,客户端发送请求时,会将Token作为请求头信息的一部分发送给服务器,服务器根据Token验证用户身份。 JWT:JWT(JSON Web Token)是一种基于JSON的开放标准,用于在各方之间安全传输信息。它由三部分组成:Header、Payload和Signature。其中,Header用于描述JWT的元数据,Payload用于存储实际传输的数据,Signature用于验证JWT的合法性。在使用JWT进行身份验证时,服务器会生成一个JWT并发送给客户端,客户端将其保存起来。之后,客户端发送请求时,会将JWT作为请求头信息的一部分发送给服务器,服务器根据JWT验证用户身份的合法性。 总结:Session、Cookie、Token和JWT都是常用于身份验证和会话管理的方法,它们各有优劣和适用场景。Session和Cookie依赖于服务器端存储用户状态,而Token和JWT则可以减轻服务器的负担,并且适用于分布式系统。其中,JWT由于其自包含性和可扩展性,在分布式系统和前后端分离的架构中得到了广泛应用。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值