Android拾萃

网络编程(二)Cookie、Session、Token、JWT

2021-08-22  本文已影响0人  三也视界

什么是认证(Authentication)

通俗地讲就是验证当前用户的身份,证明“你是你自己”(比如:你每天上下班打卡,都需要通过指纹打卡,当你的指纹和系统里录入的指纹相匹配时,就打卡成功)。

互联网中的认证

什么是授权(Authorization)

什么是凭证(Credentials)

实现认证和授权的前提是需要一种媒介(证书)来标记访问者的身份。

什么是 Cookie

HTTP 是无状态的协议(对于事务处理没有记忆能力,每次客户端和服务端会话完成时,服务端不会保存任何会话信息):每个请求都是完全独立的,服务端无法确认当前访问者的身份信息,无法分辨上一次的请求发送者和这一次的发送者是不是同一个人。所以服务器与浏览器为了进行会话跟踪(知道是谁在访问我),就必须主动的去维护一个状态,这个状态用于告知服务端前后两个请求是否来自同一浏览器。而这个状态需要通过 cookie 或者 session 去实现。

cookie 重要的属性
image.png

什么是 Session

image.png
session 认证流程

根据以上流程可知,SessionID 是连接 Cookie 和 Session 的一道桥梁,大部分系统也是根据此原理来验证用户登录状态。

Cookie 和 Session 的区别

什么是 Token(令牌)

Acesss Token

特点:

token 的身份验证流程:


image.png

每一次请求都需要携带 token,需要把 token 放到 HTTP 的 Header 里。

基于 token 的用户认证是一种服务端无状态的认证方式,服务端不用存放 token 数据。
用解析 token 的计算时间换取 session 的存储空间,从而减轻服务器的压力,减少频繁的查询数据库。

token 完全由应用管理,所以它可以避开同源策略。

Refresh Token

另外一种 token——refresh token

refresh token 是专用于刷新 access token 的 token。如果没有 refresh token,也可以刷新 access token,但每次刷新都要用户输入登录用户名与密码,会很麻烦。有了 refresh token,可以减少这个麻烦,客户端直接用 refresh token 去更新 access token,无需用户进行额外的操作。

image.png

Access Token 的有效期比较短,当 Acesss Token 由于过期而失效时,使用 Refresh Token 就可以获取到新的 Token,如果 Refresh Token 也失效了,用户就只能重新登录了。

Refresh Token 及过期时间是存储在服务器的数据库中,只有在申请新的 Acesss Token 时才会验证,不会对业务接口响应时间造成影响,也不需要向 Session 一样一直保持在内存中以应对大量的请求。

Token 和 Session 的区别

Session 是一种记录服务器和客户端会话状态的机制,使服务端有状态化,可以记录会话信息。而 Token 是令牌,访问资源接口(API)时所需要的资源凭证。Token 使服务端无状态化,不会存储会话信息。

Session 和 Token 并不矛盾,作为身份认证 Token 安全性比 Session 好,因为每一个请求都有签名还能防止监听以及重放攻击,而 Session 就必须依赖链路层来保障通讯安全了。如果你需要实现有状态的会话,仍然可以增加 Session 来在服务器端保存一些状态。

所谓 Session 认证只是简单的把 User 信息存储到 Session 里,因为 SessionID 的不可预测性,暂且认为是安全的。而 Token ,如果指的是 OAuth Token 或类似的机制的话,提供的是 认证 和 授权 ,认证是针对用户,授权是针对 App 。其目的是让某 App 有权利访问某用户的信息。这里的 Token 是唯一的。不可以转移到其它 App 上,也不可以转到其它用户上。Session 只提供一种简单的认证,即只要有此 SessionID ,即认为有此 User 的全部权利。是需要严格保密的,这个数据应该只保存在站方,不应该共享给其它网站或者第三方 App。所以简单来说:如果你的用户数据可能需要和第三方共享,或者允许第三方调用 API 接口,用 Token 。如果永远只是自己的网站,自己的 App,用什么就无所谓了。

什么是 JWT

生成 JWT

jwt.io/www.jsonwebtoken.io/

JWT 的原理
image.png
JWT 认证流程:
JWT 的使用方式

客户端收到服务器返回的 JWT,可以储存在 Cookie 里面,也可以储存在 localStorage。

当用户希望访问一个受保护的路由或者资源的时候,可以把它放在 Cookie 里面自动发送,但是这样不能跨域,所以更好的做法是放在 HTTP 请求头信息的 Authorization 字段里,使用 Bearer 模式添加 JWT。

GET /calendar/v1/events

Host: api.example.com
Authorization: Bearer <token>

跨域的时候,可以把 JWT 放在 POST 请求的数据体里。

通过 URL 传输

http://www.example.com/user?token=xxx

项目中使用 JWT

项目地址: https://github.com/yjdjiayou/jwt-demo

Token 和 JWT 的区别

相同
区别

常见的前后端鉴权方式

常见的加密算法

image.png
哈希算法

哈希算法(Hash Algorithm)又称散列算法、散列函数、哈希函数,是一种从任何一种数据中创建小的数字“指纹”的方法。哈希算法将数据重新打乱混合,重新创建一个哈希值。

哈希算法主要用来保障数据真实性(即完整性),即发信人将原始消息和哈希值一起发送,收信人通过相同的哈希函数来校验原始数据是否真实。

哈希算法通常有以下几个特点:

注意

常见问题

使用 cookie 时需要考虑的问题
Cookie是否会被覆盖,localStorage是否会被覆盖

Cookie是可以覆盖的,如果重复写入同名的Cookie,那么将会覆盖之前的Cookie
如果要删除某个Cookie,只需要新建一个同名的Cookie,并将maxAge设置为0,并添加到response中覆盖原来的Cookie。注意是0而不是负数。负数代表其他的意义。
localStorage存储在一个对象中. 有键值对
什么是localStorage,在HTML5中,新加入了一个localStorage特性,这个特性主要是用来作为本地存储来使用的,解决了cookie存储空间不足的问题(cookie中每条cookie的存储空间为4k),localStorage中一般浏览器支持的是5M大小,这个在不同的浏览器中localStorage会有所不同。
localStorage的优势
1、localStorage拓展了cookie的4K限制
2、localStorage会可以将第一次请求的数据直接存储到本地,这个相当于一个5M大小的针对于前端页面的数据库,相比于cookie可以节约带宽,但是这个却是只有在高版本的浏览器中才支持的
localStorage的局限
1、浏览器的大小不统一,并且在IE8以上的IE版本才支持localStorage这个属性
2、目前所有的浏览器中都会把localStorage的值类型限定为string类型,这个在对我们日常比较常见的JSON对象类型需要一些转换
3、localStorage在浏览器的隐私模式下面是不可读取的
4、localStorage本质上是对字符串的读取,如果存储内容多的话会消耗内存空间,会导致页面变卡
5、localStorage不能被爬虫抓取到
localStorage与sessionStorage的唯一一点区别就是localStorage属于永久性存储,而sessionStorage属于当会话结束的时候,sessionStorage中的键值对会被清空

使用 session 时需要考虑的问题
使用 token 时需要考虑的问题
使用 JWT 时需要考虑的问题
使用加密算法时需要考虑的问题

分布式架构下 session 共享方案

session 复制

任何一个服务器上的 session 发生改变(增删改),该节点会把这个 session 的所有内容序列化,然后广播给所有其它节点,不管其他服务器需不需要 session ,以此来保证 session 同步

粘性 session /IP 绑定策略

采用 Ngnix 中的 ip_hash 机制,将某个 ip 的所有请求都定向到同一台服务器上,即将用户与服务器绑定。用户第一次请求时,负载均衡器将用户的请求转发到了 A 服务器上,如果负载均衡器设置了粘性 session 的话,那么用户以后的每次请求都会转发到 A 服务器上,相当于把用户和 A 服务器粘到了一块,这就是粘性 session 机制。

session 共享(常用)

使用分布式缓存方案比如 Memcached 、Redis 来缓存 session,但是要求 Memcached 或 Redis 必须是集群

把 session 放到 Redis 中存储,虽然架构上变得复杂,并且需要多访问一次 Redis ,但是这种方案带来的好处也是很大的:

image.png
session 持久化

将 session 存储到数据库中,保证 session 的持久化

只要关闭浏览器 ,session 真的就消失了?

不对。

对 session 来说,除非程序通知服务器删除一个 session,否则服务器会一直保留,程序一般都是在用户做 log off 的时候发个指令去删除 session。然而浏览器从来不会主动在关闭之前通知服务器它将要关闭,因此服务器根本不会有机会知道浏览器已经关闭,之所以会有这种错觉,是大部分 session 机制都使用会话 cookie 来保存 session id,而关闭浏览器后这个 session id 就消失了,再次连接服务器时也就无法找到原来的 session。

如果服务器设置的 cookie 被保存在硬盘上,或者使用某种手段改写浏览器发出的 HTTP 请求头,把原来的 session id 发送给服务器,则再次打开浏览器仍然能够打开原来的 session。

恰恰是由于关闭浏览器不会导致 session 被删除,迫使服务器为 session 设置了一个失效时间,当距离客户端上一次使用 session 的时间超过这个失效时间时,服务器就认为客户端已经停止了活动,才会把 session 删除以节省存储空间。

上一篇 下一篇

猜你喜欢

热点阅读