Session --VS--Cookie

本文介绍会话管理技术,包括Cookie和Session的区别、工作原理及应用场景。详细解释了Cookie的属性、读写方式、类型和Session的创建、生命周期管理等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

什么是会话?

用户打开浏览器,访问一个网站进行一系列操作,关闭浏览器离开,完整过程 就是会话


Cookie : 一种将用户信息保存在客户端技术 ,客户端会将cookie信息自动发送给服务器


Session :一种将用户信息保存在服务器端技术 ,客户端(cookies中)会持有Session信息对应key,通过key找到session信息


Session 占用服务器空间,安全性更高 ,Cookie节省服务器资源,安全性差一些。


1、Cookie是什么?有什么属性

1.1属性:

        name:Cookie的名称。必须的。
        value:对应的值。必须的。
        maxAge:最大值。Cookie生命时长。默认是一次会话过程,它是存在于浏览器的进程中---内存。
        domain:域名。
        path:路径。默认是当前写Cookie的那个程序的访问路径
        comment:注释,备注
        version:版本号

       

        如果写的Cookie的路径是:   /day05/servlet/

               当访问的新的资源路径是:http://localhost:8080/day05/CookieDemo1    浏览器不会带上刚才的Cookie。
       如果写的Cookie的路径是:/day05
                 当访问的新的资源路径是:http://localhost:8080/day05/servlet/CookieDemo1  浏览器会带上刚才的Cookie。
                 
       浏览器带不带上自己缓存的Cookie:域名要一样。当前访问的资源的路径.startWith(Cookie的路径),为true就带。
                         

        1.2特点:

        每个浏览器针对一个网站最多能存20个Cookie,总共300个,且每个Cookie的大小不能超过4KB。要使用Cookie存放尽可能少的关键数据。
                       

        1.3Cookie的读写:

        写给客户端:HttpServletResponse.addCookie(Cookie c),  实际上就是写了一个响应消息头:Set-Cookie:cookiename=cookievalue

        读客户端的Cookie:HttpServletRequest.getCookies()  ,    实际上就是读取一个请求消息头:Cookie:cookiename=cookievalue


        1.4如何唯一确定一个Cookie:

          domain+path+name

  

        localhost/day05_cookieSession/servlet  lastAccessTime

        localhost+/day05_cookieSession/servlet+lastAccessTime


        1.5如何删掉指定的Cookie

                设置Cookie的生命时间为0,写回客户端。
                要想删除成功:domian+path+name必须一样(不严格)

                       
                Cookie cookie = new Cookie("lastAccessTime","");
                cookie.setMaxAge(0);

                response.addCookie(cookie);


1.6 Cookie API 详解

1 读取cookie
         request.getCookies() 返回Cookie[]
首先判断cookies数组是否存在 cookies == null,如果cookies存在,根据cookie的name去查找指定cookie

2、服务器向客户端发送cookie
cookie对象创建 new Cookie(name,value)
response.addCookie(cookie) 将cookie发送客户端

* cookie有name和value,提供三个方法 getName getValue setValue  


3、cookie从持久性上分为两类 会话cookie和持久cookie


   会话cookie 保存在浏览器内存中cookie,当会话结束浏览器关闭,会话cookie信息就是丢失
   持久cookie 保存在浏览器临时文件缓存区中cookie (硬盘上) ,当关闭浏览器结束会话,持久cookie不会被删除
   持久cookie存在过期时间,过期后会自动删除
   持久cookie 需要设置cookie 有效期 setMaxAge

  Set-Cookie: lastvisit=1350617047968; Expires=Fri, 19-Oct-2012 04:24:07 GMT


4、cookie访问有效路
携带cookie 必须path一致
默认 http://localhost/day7/visit 生成cookie ---- 默认path 就是/day7/ (visit资源所在目录就是默认path)
* 只有在访问 http://localhost/day7/ 目录和子目录情况下 才会携带cookie 信息
path也可以手动指定 setPath
newLastVisitCookie.setPath("/abc");
抓取信息:
Set-Cookie: lastvisit=1350617427109; Expires=Fri, 19-Oct-2012 04:30:27 GMT; Path=/abc
再次访问 :http://localhost/day7/visit 不会携带cookie信息,因为path 不符合

最简单方案:setPath("/");

Set-Cookie: lastvisit=1350617644468; Expires=Fri, 19-Oct-2012 04:34:04 GMT; Path=/


5、cookie有效域名
setDomain 设置cookie有效域名 ---- 例如:setDomain(".itcast.cn"); 传智播客网站的cookie

访问A 网站 ,生成 B网站 Cookie  ----- 第三方cookie (恶意cookie)

访问A 网站, 生成A 网站Cookie ----- 第一方Cookie(安全cookie )


6、删除持久cookie
     删除持久cookie,可以将cookie最大时效设为0,注意,删除cookie时,path必须一致,否则不会删除

记录上次访问时间案例


1、第一次访问VisitServlet
请求中没有cookie信息
响应中 Set-Cookie: lastvisit=1350615153109

* Cookie信息保存浏览器缓存中


2、第二次访问VisitServlet
请求中 Cookie: lastvisit=1350615153109
响应中 Set-Cookie: lastvisit=1350615241359
默认cookie都是浏览器内存中进行缓存的 ,当浏览器关闭,会话结束,内存释放
* 从request请求中查找 指定name的cookie信息
public Cookie findCookie(Cookie[] cookies, String name) {
                if (cookies == null) {
                        // 不存在任何cookie
                        return null;
                } else {
                        // 存在cookie,查找指定cookie
                        for (Cookie cookie : cookies) {
                                if (cookie.getName().equals(name)) {
                                        // 找到了
                                        return cookie;
                                }
                        }
                        // 没有找到
                        return null;
                }
        }
* 服务器端向客户端写出一个新的cookie
Cookie newLastVisitCookie = new Cookie("lastvisit", System.currentTimeMillis()+ "");
response.addCookie(newLastVisitCookie);

二 Session的原理:


Session 将用户相关信息保存服务器端,服务器会为每个浏览器创建单独Session对象,每个用户各自数据 保存各自浏览器对应Session对象中。不同用户 获取到各自浏览器对应Session 保存数据。


Session对象创建 : request.getSession();

服务器端会为每个浏览器创建单独Session对象,如何做到的? 


Session 通过cookie 传输 JSESSIONID 用来在服务器端查找对应Session对象


问题:如何实现关掉浏览器后,再开浏览器,上次购买的商品还在。

1、第一次访问 响应
Set-Cookie: JSESSIONID=7B67782D880A07ADADA64A312ED23D72; Path=/day7
2、第二次访问 请求
Cookie: JSESSIONID=7B67782D880A07ADADA64A312ED23D72
   关闭浏览器重新打开

3、直接访问 session2 : 无法访问刚才Session信息

解决方案:将jsessionid 信息保存 持久Cookie
                Cookie cookie = new Cookie("JSESSIONID", session.getId());
                cookie.setMaxAge(60 * 60 * 24);
                cookie.setPath("/");
                response.addCookie(cookie);
抓取响应
Set-Cookie: JSESSIONID=4E14F3FD831BDAD3C532C13568EEA358; Path=/day7

Set-Cookie:JSESSIONID=4E14F3FD831BDAD3C532C13568EEA358;Expires=Sat, 20-Oct-2012 06:37:50 GMT; Path=/


      浏览器禁用Cookie之后,Session还能否使用 ? 可以的,但浏览器无法保存cookie中jsession id ,无法完成Session追踪

JSESSIONID=985E0B491708994C0039BEFC0B277056; Path=/day7


第二次请求服务器:
http://localhost/day7/session2;jsessionid=985E0B491708994C0039BEFC0B277056
通过程序生成URL (携带jsessionid的URL ) : URL重写

使用URL重写,必须该网站所有路径都使用URL重写 ,实际应用中很少采用


Session的生命周期

1、Session对象创建 : request.getSession() 执行时 (当前会话第一次执行)


2浏览器如果关闭后,Session对象是不是就销毁了?

    不是,Session保存在服务器端,和浏览器是否关闭没有关系 ,关闭浏览器时删除会话cookie,丢失jsessionid,没有jsession无法找到服务器端对应Session


三种销毁Session对象情况:


1、不正常关闭服务器(正常关闭服务器Session信息会被序列化到硬盘中 保存tomcat/work目录)


2、Session过期 默认过期时间在tomcat/conf/web.xml 配置
<session-config>
        <session-timeout>30</session-timeout>
</session-config>
* 默认Session对象过期时间30分钟 (连续不使用Session对象时间)

* 也可以手动设置 setMaxInactiveInterval(int interval)  


3、在程序中执行 session.invalidate() 手动销毁Session对象


问题:session.removeAttribute 和 session.invalidate区别 ?


session.removeAttribute  删除当前Session对象中一个属性值
session.invalidate 销毁当前Session对象,删除所有属性


用户之间没有影响 (用户购物车、用户登录信息 )


Servlet三种数据访问范围:ServletContext 、HttpSession、HttpServletRequest


1、保存ServletContext数据 ,在服务器关闭时才会删除,生命周期最长,全局都可以访问 (最少使用)
*   网站访问次数、全局数据库连接池 需要保存ServletContext
2、保存HttpSession数据 ,三种情况下丢失 ,主要保存用户相关数据 (不建议存放大规模数据)
* 用户登录信息、购物信息 保存HttpSession
3、保存HttpServletRequest,当前请求发生时产生,响应结束数据立刻释放 (生命周期最短,最建议使用)

* Servlet获得数据处理结果,通过请求转发 传递信息给JSP显示


  ServletContext 每个web工程对应唯一对象,全局的Servlet上下文对象,允许将数据保存ServletContext 。所有   Servlet共享。

        HttpServletRequest 每次请求产生一个HttpServletRequest对象,允许将数据保存request对象中,结合请求转发一起使用当请求结束后,数据就会删除。
         HttpSession 服务器会为每个客户端创建单独Session对象,允许将数据保存session中 ,session保存的是每个用户各自的数据


三种数据范围提供相同几个方法
setAttribute
getAttribute
removeAttribute

PS :内容小结:


1、Cookie和Session区别 ?

       Cookie保存会话信息在客户端,Session保存会话信息在服务器端,Session基于Cookie实现的


2、Session安全吗?

     相对Cookie安全,不是绝对安全 ,jsessionid 可以伪装,二次验证必要性


3、浏览器关闭后,是不是Session对象就销毁了 ?

      不是,Session保存在服务器端,关闭浏览器丢失jsessionid,无法找到服务器对应Session对象了,需要等到Session过期后才会销毁


4、禁用浏览器cookie后,Session还能否使用?

      可以,URL重写


5、会话cookie和持久cookie区别 ?

      会话cookie 保存浏览器内存缓存区中,关闭浏览器后,会话cookie就会删除

      持久cookie 保存浏览器临时文件区 硬盘上,存在过期时间,当过期后会自动删除,通过设置maxage为0删除持久cookie


6、session的三种销毁原因?

     服务器非正常关闭、session过期、invalidate


7、如何实现关闭浏览器再次打开,Session仍然可以访问?

       将jsessionid 对应cookie 持久化

<think>好的,用户现在想了解token和session-cookie之间的区别,以及它们的用法比较。我需要先回顾之前的对话,确保回答的一致性和相关性。 用户之前问过token是什么,我详细解释了token的定义、用途,包括身份验证、授权、跨域资源共享和API访问控制,还提供了JWT的代码示例。现在用户进一步想了解token和session-cookie的区别,需要对比这两者的工作机制、安全性、扩展性等方面。 首先,我需要明确session-cookie和token-based认证的基本原理。session-cookie是服务器存储会话信息,客户端通过cookie保存session ID,而token-based则是服务器生成token,客户端存储token,每次请求携带token进行验证。 接下来,对比两者的存储位置。session数据存储在服务器端,可能使用内存、数据库或缓存,而token的数据通常存储在客户端,如JWT包含用户信息。这点需要强调服务器负担和扩展性的问题。 然后是安全性。session ID可能面临CSRF攻击,而token一般不需要cookie,可以避免CSRF,但需要注意XSS攻击的风险。同时,token如果使用JWT,需要保护密钥,防止被篡改。 跨域支持方面,session-cookie受同源策略限制,而token可以灵活地在不同域之间传递,适合现代前后端分离的应用架构。 扩展性方面,session需要服务器存储,对于分布式系统可能需要共享session存储,而token无状态,更适合水平扩展。 另外,用户可能关心的实际应用场景,比如移动应用或RESTful API通常用token,而传统Web应用可能用session-cookie。需要举例说明两者的适用情况。 还需要检查之前的引用文献,确保引用的一致性。之前的回答引用了[^1][^3][^4][^5],可能需要调整引用位置,确保准确。 可能用户需要具体的例子或代码比较,比如session-cookie的实现和token的实现对比,或者如何选择适合的方案。 最后,生成的相关问题需要与主题紧密相关,比如如何防止token被盗,分布式系统中的认证方案选择,或者迁移session到token的注意事项。确保问题能引导用户深入思考或进一步学习。</think>### Token 与 Session-Cookie 的区别及用法比较 在用户身份验证和会话管理领域,**Token** 和 **Session-Cookie** 是两种主流方案,它们在存储方式、安全性、扩展性等方面有显著差异。以下是具体分析: --- #### 1. **核心机制对比** | **特性** | **Session-Cookie** | **Token** | |------------------------|-------------------------------------------------|------------------------------------------------| | **存储位置** | 服务器端存储会话数据,客户端仅存储 Session ID(通过 Cookie) | Token 存储在客户端(如浏览器 LocalStorage、HTTP 头) | | **状态性** | 有状态(服务器需维护会话状态) | 无状态(服务器不存储会话信息) | | **通信方式** | 依赖 Cookie 自动附加到请求头 | 需手动将 Token 添加到请求头(如 `Authorization: Bearer <token>`) | | **跨域支持** | 受同源策略限制(需配置 CORS) | 天然支持跨域(通过自定义 HTTP 头传递) | --- #### 2. **安全性对比** ##### (1)**Session-Cookie 的风险** - **CSRF(跨站请求伪造)**:攻击者可诱导用户点击恶意链接,利用浏览器自动携带 Cookie 的特性发起非法请求[^3]。 - **XSS(跨站脚本攻击)**:若 Cookie 未设置 `HttpOnly` 属性,攻击者可通过注入脚本窃取 Session ID[^1]。 - **防御措施**:需配合 CSRF Token、设置 `SameSite` 属性(如 `SameSite=Strict`)等增强安全性。 ##### (2)**Token 的风险** - **XSS 攻击**:若 Token 存储在 LocalStorage 中,可能被恶意脚本窃取[^5]。 - **Token 泄露**:需使用 HTTPS 加密传输,防止中间人攻击。 - **防御措施**:短期 Token 有效期、JWT 签名验证(如 HS256 或 RS256)、黑名单机制等。 --- #### 3. **性能与扩展性对比** | **场景** | **Session-Cookie** | **Token** | |------------------------|-------------------------------------------------|------------------------------------------------| | **服务器资源占用** | 需在服务器端存储会话数据,可能占用内存或数据库资源 | 无服务器端存储,减轻负载 | | **分布式系统支持** | 需共享 Session 存储(如 Redis 集群) | 天然支持分布式(Token 自包含用户信息) | | **移动端/API 友好性** | 依赖 Cookie,对原生移动端支持较差 | 更适合移动端和 RESTful API | --- #### 4. **典型应用场景** ##### (1)**Session-Cookie 适用场景** - **传统 Web 应用**:如电商网站、内容管理系统(CMS),需要服务器维护用户状态。 - **需要短期会话**:例如银行系统,要求会话严格受控并快速失效。 ##### (2)**Token 适用场景** - **前后端分离架构**:如 SPA(单页应用)、移动端 App,通过 Token 实现跨域认证[^4]。 - **微服务/分布式系统**:无需共享 Session 存储,降低系统耦合度。 - **第三方 API 授权**:如 OAuth2.0 中的 Access Token[^5]。 --- #### 5. **代码示例对比** ##### (1)Session-Cookie 实现(Node.js) ```javascript // 服务器生成 Session ID 并存储 const session = require('express-session'); app.use(session({ secret: 'your_secret_key', resave: false, saveUninitialized: true, cookie: { secure: true, httpOnly: true } })); // 登录后设置 Session app.post('/login', (req, res) => { req.session.userId = 123; // 服务器存储用户 ID res.send('Logged in'); }); ``` ##### (2)Token 实现(JWT) ```javascript const jwt = require('jsonwebtoken'); // 生成 Token const token = jwt.sign({ userId: 123 }, 'your_secret_key', { expiresIn: '1h' }); // 客户端请求时携带 Token fetch('/api/data', { headers: { 'Authorization': `Bearer ${token}` } }); ``` --- ### 总结:如何选择? - **需要高扩展性、跨域支持** → 选择 **Token**(如 JWT)。 - **需严格控制会话状态、防范 XSS** → 选择 **Session-Cookie**(配合安全配置)。 - **混合方案**:某些场景可结合两者(如使用 Session 管理短期操作,Token 用于长期授权)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值