Day25 来人上菜! 给我来点Cookie and Session

前言:

一直以来都知道网页有Cookie,甚至有时候网页跑不出来的时候很多人的建议都是清除Cookie,但直到我需要用到前,都没有好好了解过到底Cookie指的是什麽,同时也延伸了何谓Session,今天我们就要来了解两者以及差别!!

HTTP

HTTP 是一个无状态**(stateless)**的通讯协定,可以在Client与Server两端进行沟通,但无法纪录网路上的行为,服务器并不会记住使用者是谁,而是每一次收到的请求视为独立的行为。

如果是纯粹展示静态内容的网站,无状态不会是问题,HTTP是很棒的优点,因为client客户端、server服务器、database资料库都不需要储存使用者的状态、资料,省去了大量的储存空间;但在复杂的网路应用、动态网页时,比如要登入一个网站或是网页上填资料时,每次访问该网站,就需要将再输入一次(因为每次请求都不会留下资料),需要辨别使用者身分时,无状态的通讯就会是个问题。

那该怎麽解决 HTTP 无纪录状态的问题,该怎麽做呢?

Session 和 Cookie 的主要目的就是为了弥补 HTTP 的无状态特性。

Cookie

Cookie(小饼乾或称小型文字档案) 就是用来解决HTTP的无状态特性的手段之一,是一段由服务器送给使用者浏览器的一小块资料(文档)。

Cookie 应用例如:在资料填写上,有时候手滑跑出去,但再回来页面的时候发现刚刚填的资讯都还在,这其中靠的就是 cookie, 服务器可以设定或读取Cookies中所包含资讯,只要Cookie尚未到期,浏览器会传送该Cookie给服务器作验证凭据,来避免HTTP无状态性的问题。

Cookie设定值是储存在使用者的电脑里,可透过浏览器来检测这个设定值是否储存,开启浏览器,输入要查看网址点选左上角的小图示

client 端的程序在一旦填写的资料有变动时,就把该资讯写入 Cookie。

Cookie 虽然好用,但有弊端,Cookie 中的所有数据在Client端就可以被修改,数据非常容易被伪造,那麽一些重要的数据就不能存放在cookie 中了,或是数据太多反而影响传输效率等,为了解决这些问题,session就诞生了! session 中的数据是保留在Server端。

Session

#RFC 2109
This document describes a way to create stateful sessions with HTTP requests and responses. Currently, HTTP servers respond to each client request without relating that request to previous or subsequent requests; the technique allows clients and servers that wish to exchange state information to place HTTP requests and responses within a larger context, which we term a "session".

Session定义,真的难懂,不过简单来说,Session 所代表的是「状态」,如果没有了状态,一大堆功能都会失效。

Session负责纪录在 Server端上的使用者讯息,会在一个用户完成身分认证後,存下所需的用户资料,接着产生一组对应的 ID(Session ID),存入 Cookie 後传回用户端。

所以我们可以想像Cookie是一张领据,而Session是一张会员卡,上面记录了一些资料,当我们提出请求Request,服务器端Server(老板)会根据你专属的Session ID,回应给你需要的东西,但如果你是新会员没有纪录(客户端请求不包含Session id),则表示你是新脸孔,那Server就为此客户端创建一个Session,并生成一个Session id,并返回给客户端保存。

可以采用Cookie保存这个Session id,很多人都有一种彷佛浏览器关掉Session也会消失的错觉,实际上关闭浏览器不会导致Session被删除,像银行卡,除非你主动提出销卡,否则不会删除资料,通常Server为Seesion设置了一个失效时间(默认30分钟)保存这个Session,过了时间就会销毁这个Session,但程序设计师通常会保存起来,好处是没了时间的限制,坏处是随着时间的增加,这个资料库会急速膨胀,特别是访问量增加的时候,因此当服务器认为Client客户端已经停止了活动,会把session删除以节省存储空间,以减轻服务器压力。

  • 不过不知道有没有读者想到一个问题,那就是Cookie和Session有没有被窜改的问题?

Cookie 被拿来解密窜改,假设今天我是一般会员“Winnie”,我把自己改成VIP会员“Ritabear”,伪装成另外一个身分,那我能用的权限就高了,这个时候就要靠SignedCooke 签章验证资料的真实性,使用Cookie时,可以加一个签章,也就是在我传输的资料後面加上一个对应的秘密字串,当服务器回传时,可以回应该字串,让我们的Cookie不容易被窜改,由於串改的资料和我的秘密字串无法相符,当然也无法作伪造,这就是所谓的 SignedCookie。

  • 总结:

    引入 Cookie 与 Set-Cookie 两个 Header 来建立 Session。

    服务器透过 Header 的属性 Set-Cookie,把使用者的状态纪录储存在使用者电脑里的 Cookie,而浏览器在每一次发送Request时,都在 Header 中设定 Cookie 属性,把 Cookie 带上,服务器就能藉由检视 Cookie 的内容,得知浏览器使用者的状态;而像是「从登入到登出」、「从开始浏览网页到 Cookie 失效」,或是任何服务器能认出使用者状态的时间区间,就叫做 Session

    建立 Session 之後,所储存的状态就叫做 Session information,若是选择把这些资讯存在 Cookie 里面,就叫做 Cookie-based session;还有另一种方法则是在 Cookie 里面只存一个 SessionID,其他的 Session 资讯都存在 Server 端,靠着这个 ID 把两者关联起来。

Cookie Session
基本定义 小文件,记录一些对网站的个人设定 状态
资料储存 存放在Client端(不会造成服务器端的过载) 储存在Server端
提醒 SessionID写在里面 一个SessionID对应一笔SessionID
失效 存在用户端的cookie,不会因为浏览器的关闭消失(直到时效失效为止) Session 在服务器端并不会自动失效,除非session已经超过设置的失效时间。
风险 Cookie传送时是以明码方式传送,机密资料不建议以此方式储存

PS. expires是过期的意思,所以这是个一天之後就会过期的Cookie。如果不设定的话,在关掉浏览器的时候Cookie就会被清除。

服务器把状态放在 Set-Cookie 这个 Header 里面送去浏览器,而浏览器在之後的 Request 把 Cookie 带上去,这样子就成立一个 Session 了,因为後续的 Request 就有了状态。


<<:  D30 - 用 Swift 和公开资讯,打造投资理财的 Apps { 台股申购功能扩充,算出价差 }

>>:  Day25 实作MiddleWare(2)

Electron - 今晚我想来点 Electron 加 Vue.js

前几篇介绍了 Electron 如何操作,既然 Electron 是将网页包起来,那当然可以使用 V...

day25_如何采购 ARM 版本的 Windows 电脑呢

ARM 版本的 Windows 该怎麽买呢? 主要的产品为 Surface Pro X ,这是一款微...

#3 JavaScript Crash Course 2

今天教 Promise Async / Await。 Promise Promise 这个东西跟时间...

[Golang]同步工具-sync包的Cond-心智图总结

1. sync包的Cond,提供条件变数。 a. 条件变数是基於互斥锁的,它必须有互斥锁的支撑,才能...

[版本更新] 重点速记 ubuntu 21.10 (含呒虾米安装建议)

前言 ※本篇早先已於 110 年 10 月 15 日发布在我的部落格:[版本更新] 重点速记 ubu...