请求中的cookiesession和token
Posted 恪愚
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了请求中的cookiesession和token相关的知识,希望对你有一定的参考价值。
首先要明确几个概念:
- 这三个的诞生源于“HTTP是一个无状态的协议”;
- session是保存到服务端的,而cookie是保存到客户端的(通常说“cookie是实现session的一种方案”或者说“cookie是客户端保存session的载体”);
- token和前两者不同;
session和cookie
其目的是在http的无状态性下,为了使某个域名下的所有网页能够共享某些数据产生的一种手段。它们在客户端对服务端的访问中的运作方式如下:
- 客户端发送的请求在被服务器端接受后,会在服务端建立一个
session
,并返回一个http响应到客户端,这个响应包含的响应头中有一个Set-Cookie
头部。里面包含了sessionId
。Set-Cookie格式如:Set-Cookie: value[; expires=date][; domain=domain][; path=path][; secure]
; - 在客户端发起的第二次请求,假如上一次时服务器给了
set-Cookie
,浏览器会自动在请求头中添加cookie
; - 服务器接收请求,分解cookie,验证信息,核对(和保存的session比较)成功后返回response给客户端;
这里面有两点需要注意:
- 上面提到了
expires
(设置的是绝对时间),是http1.0的产物,它会导致一些问题:客户端和服务器时间不同步导致expires
的配置出现问题;很容易在配置后忘记具体的过期时间,导致过期来临出现浪涌现象。所以在http1.1提出了max-age
(设置的是相对文档第一次被请求时服务器记录的Request_time时间)。但是max-age
隶属于Cache-Control
字段。Expires和Cache-Control两个字段都是响应头中用来控制强缓存的存在,但Cache-Control优先级较高。 - 什么是“HTTP无状态”?在点击一个纯的html网页,请求获取服务器的html文件资源时,每次http请求都会返回同样的信息,因为这个是没有交互的,每一次的请求都是相互独立的。这样在交互时却不适用,因为浏览器会“立即忘记你是谁”。
假如在一个购物的场景下:
第一步验证登录者是一个合法用户,验证通过给你返回200/OK
,但是只要服务器给返回了响应,那么一个http的请求和响应就结束了。服务器怎么知道10秒钟之前你刚刚登录过呢?不好意思,服务器不知道你有没有登陆过,他只是对外提供一个登录接口,要想证明你是合法用户必须调/login
接口。
第二步,将商品加入到购物车中时,你会调用/cart
接口,但是注意,这个行为是和第一步没有关联的,是谁将什么物品加入到购物车中了?这个谁,有没有在网站上注册账号呢,是不是一个合法用户呢?所以说在添加购物车的时候,我们还需要将账号密码再次加入到请求参数中,每做一次操作购物车操作时,都需要再把之前已经传输过的账号密码,再反反复复的传输一遍又一遍,这只是因为服务器不知道你是不是在20秒之前刚登陆过!
如果只是单纯的这样,会带来极大的安全隐患和体验感的下降:明明只需要在/login
接口中,才需要对比数据库中的账号密码和客户端传的是否一致来确定合法性。这下在添加购物车中也需要再一次的进行同样的重复且没有必要的操作,即降低了响应速度,又对用户不友好(因为每次都需要填账号,密码)。
为此,我们可以用提到的cookie和session来做校验。就避免了上述情况的发生!
- cookie只是实现session的其中一种方案。虽然是最常用的,但并不是唯一的方法。禁用cookie后还有其他方法存储,比如放在url中。但是不可能将信息全部保存在客户端,否则一旦被劫持,全部信息都会泄露。并且客户端数据量变大,网络传输的数据量也会变大。
token
token 也称作令牌,其认证方式类似于临时的证书签名, 并且是一种服务端无状态的认证方式, 非常适合于 REST API 的场景.,因为上面说了无状态就是服务端并不会保存身份认证相关的数据。
token组成:
- uid: 用户唯一身份标识
- time: 当前时间的时间戳
- sign: 签名, 使用 hash/encrypt 压缩成定长的十六进制字符串,以防止第三方恶意拼接
- 固定参数(可选): 将一些常用的固定参数加入到 token 中是为了避免重复查库
token在客户端一般存放于localStorage
,cookie
,或sessionStorage
中。在服务器一般存于数据库中。
token 的认证流程与cookie很相似:
- 用户登录,成功后服务器返回
token
给客户端(以header的形式response.setHeader
或是以参数的形式jwt
); - 客户端收到数据后保存在客户端;
- 客户端再次访问服务器,将
token
放入headers
中 或者 将token保存在页面中的“隐藏域”中,随post一起发送到后端<input calss="csrfToken" type="hidden" name="csrfToken" value="xxx" />
; - 服务器端采用
filter
过滤器校验。校验成功则返回请求数据,校验失败则返回错误码;
但对于token来说,浏览器不会自动添加到headers里,攻击者也无法访问用户的token,所以提交的表单无法通过服务器过滤,也就无法形成csrf攻击。
现在常说的“jwt(JSON Web Token)权鉴”机制就是token的一种实现方式。
最近在带着学弟学妹们一起搞一个项目,等笔者搞到相关代码再来补充[/:滑稽脸]。溜了…
以上是关于请求中的cookiesession和token的主要内容,如果未能解决你的问题,请参考以下文章
系统开发系列 之web开发中cookiesession和token的使用