现在做web的话就绕不开安全认证这一步,那就先介绍下目前常见的认证方式然后再说关于cookie、session、token的东西。常用的认证方式简单概述如下:
- cookie-session认证方式
出现较早的认证方式,主要形式是浏览器客户端将用户名密码发送给服务器,服务器验证后创建session并发放用于识别用户的sessionID(与用户状态绑定后记录在服务器端),这个sessionID以及一些相关的其他信息就是cookie,cookie随着响应(Set-Cookie)返回给客户端由客户端存储于浏览器,之后客户端的请求都会带上这个cookie,服务端通过cookie来获取Session信息从而进行认证校验。
- Oauth认证方式
Oauth是一种授权机制,主要为第三方应用颁发授权令牌(token),目前有Oauth2.0和Oauth1.0版本,其中Oauth2.0版本的标准是RFC6749,Oauth1.0版本的标准是RFC5849。Oauth2.0的具体介绍可以参考阮一峰|Oauth2.0
- JWT认证方式
JWT的标准是RFC7519。大概原理是客户端经过服务器认证后服务器给客户端返回一个json对象(包含用户信息且加密处理的数据),之后客户端与服务器通信都会带上这个json对象,服务器只通过这个对象来认证用户,也就是说服务器端是无状态的不会保存状态数据了(比如session)。具体可参考阮一峰|JSON Web Token 入门教程
概念梳理
- Cookie
Cookie(复数形态Cookies),又称为“小甜饼”。类型为“小型文本文件”[1],指某些网站为了辨别用户身份而储存在用户本地终端(Client Side)上的数据(通常经过加密)。由网景公司的前雇员卢·蒙特利在1993年3月发明[2]。最初定义于RFC 2109。当前使用最广泛的 Cookie标准却不是RFC中定义的任何一个,而是在网景公司制定的标准上进行扩展后的产物。
Cookie总是保存在客户端中,按在客户端中的存储位置,可分为内存Cookie和硬盘Cookie。内存Cookie由浏览器维护,保存在内存中,浏览器关闭后就消失了,其存在时间是短暂的。硬盘Cookie保存在硬盘里,有一个过期时间,除非用户手工清理或到了过期时间,硬盘Cookie不会被删除,其存在时间是长期的。所以,按存在时间,可分为非持久Cookie和持久Cookie。
Cookie就是用来绕开HTTP的无状态性的“额外手段”之一。服务器可以设置或读取Cookies中包含信息,借此维护用户跟服务器会话中的状态
使用Cookie的缺陷:
- Cookie会被附加在每个HTTP请求中,所以无形中增加了流量
- 由于在HTTP请求中的Cookie是明文传递的,所以安全性成问题,除非用HTTPS
- Cookie的大小限制在4KB左右,对于复杂的存储需求来说是不够用的
–选自Wikipedia
- Session
跟上面cookie不同,cookie是实际存在的,而session是一个抽象概念,我们更多说的是session的实现。session其实就是服务器用来保存用户会话状态(因为HTTP是一个无状态的协议)的一种机制。
服务器session存放在服务器(默认存在文件也可以存在内存、数据库中),运行需要依赖于session id,不过一般session id会存在客户端cookie中(当然如果浏览器禁用cookie的话,也可以通过其他方式实现,比如通过url来传递)
- Token
这里说的token是access token,仅仅是指访问资源凭证,是跟上面说的Oauth认证相关的。主要针对的是从第三方应用获得授权登录,客户端从第三方应用获取的授权登录令牌,我们就称为token。
代码示例(Flask)
下面就FLask来做一些代码演示
Demo-1(逻辑演示)
如果不使用session-cookie机制,我们也可以实现用户的登录控制,下面这个非常简陋只是为了演示下登录验证的思路,不必纠结细节,极其不pythonic,代码臃肿且不科学。说一下下面的问题
- 缺失判断来源的逻辑(应该增加判断条件更准确的鉴别请求来源)
- 每次都需要重新登录验证
|
|
demo-2(使用session-cookie)
使用session-cookie的话,如下
在下面的例子中当键入用户密码发出POST请求后,服务器的response是Set-cookie:session=eyJnb3VyZHMiOiJnb3VyZHMtc2Vzc2lvbiJ9.EEaMcA.eV2X1jpYYTAZePmRTT5cdYhUfXw; HttpOnly; Path=/
,从浏览器开发者模式可以看到这个值存放在浏览器cookies
下,然后访问其他页面时请求头(Request headers:session=eyJnb3VyZHMiOiJnb3VyZHMtc2Vzc2lvbiJ9.EEaMcA.eV2X1jpYYTAZePmRTT5cdYhUfXw
)会带上这个cookiesession=eyJnb3VyZHMiOiJnb3VyZHMtc2Vzc2lvbiJ9.EEaMcA.eV2X1jpYYTAZePmRTT5cdYhUfXw
,就避免了每次输入账号密码的尴尬了。如果在浏览器在这个cookie删除或者禁用,就不能正常访问了。
|
|
Demo-3(使用Flask的特殊装饰符)
使用Flask的特殊装饰符
|
|