仅供个人学习,大量借鉴他人文本,如果需要请直接移步文章 前端鉴权知识学习 , 关于鉴权,看懂这篇就够了前端面试查漏补缺, JSON Web Token 入门教程
鉴权方式有哪些
- HTTP Basic Authentication (HTTP基本认证)
- cookie-session
- Token 验证(包括JWT,SSO)
- OAuth(开放授权)
HTTP Basic Authentication
- http协议实现的基本鉴权方式
- 客户端向服务端发送请求
Get /index.html HTTP/1.0
Host:www.google.com
- 服务端返回401,浏览器会自动弹出输入用户名和密码的弹框
HTTP/1.0 401 Unauthorised
Server: SokEvo/1.0
WWW-Authenticate: Basic realm=”google.com”
Content-Type: text/html
Content-Length: xxx
- 输入完用户名和密码后,浏览器会再重新发送请求,新的请求会将用户名和密码加密后放到Authorization字段
HTTP/1.0 401 Unauthorised
Server: SokEvo/1.0
WWW-Authenticate: Basic realm=”google.com”
Content-Type: text/html
Content-Length: xxx
- 服务端收到新的请求后,解析Authorization字段,如果符合,那就返回对应的请求数据
这种方式已经很少使用了,了解下就好
cookie-session
说cookie-session之前需要先说cookie
什么是cookie
HTTP 协议中的 Cookie 包括 Web Cookie 和浏览器 Cookie,它是服务器发送到 Web 浏览器的一小块数据。服务器发送到浏览器的 Cookie,浏览器会进行存储,并与下一个请求一起发送到服务器。通常,它用于判断两个请求是否来自于同一个浏览器,例如用户保持登录状态
- 客户端
第一次请求(登录),由服务器端生成并返回 - 客户端(浏览器)会
把cookie以key-value的形式保存到本地文件夹中 - 下次请求同一服务时,会在
header上带上这个cookie
cookie的类型
- Session Cookies: 会话cookie,放在内存中,会随浏览器关闭而删除;
然而Web浏览器可能会使用会话还原,这会使大多数会话 Cookie 保持永久状态,就像从未关闭过浏览器一样。 - Persistent Cookies: 持续性cookie, 放在磁盘中,有
Expires或Max-Age指令,用于指定什么时候过期;
Expires或Max-Age属性是区分Session Cookies和Persistent Cookies主要依据
cookie 的特点
- 因为保存在本地,所以容易被篡改,不安全
- 因为cookie是会放在http请求中的,所以会影响性能。不能大于
4KB - 浏览器对同一网页一般只能存不超过
20个cookie, 且浏览器一般最多只能存300个cookie 移动端对cookie支持不友好- 一般
存储的是纯文本,对象需要序列化后才能存储,解析需要反序列化
cookie-session
由于cookie的大小限制和浏览器对cookie的数量限制等,开发人员使用在服务器生成一个sessionID对应一个用户,具体操作如下
- 客户端首次请求(登录),服务器会创建一个session,并生成一个sessionID,然后将session和sessionID以key-Value的形式缓存到
缓存服务器中,同时返回给客户端sessionID。 - 下次客户端请求时,带上这个sessionID, 服务器会先拿着这个sessionID去查session,如果存在session再去做具体的请求操作
- cookie-session 原理图
什么这里增加了一个缓存服务器?1.如果直接将用户信息存在服务器当中会,会给服务器造成极大的性能损耗 2.如果这个服务被转发给其他服务器,session也就失效了
cookie-session 局限性
- 如果这个
缓存服务器挂了,那么所有的服务就挂了,所以一般中项目会部署多台集群服务器用于session - 依赖cookie,用户可以客户端禁用cookie
- 业务请求会不停的请求缓存服务器,查找用户信息,这样内存就会增加,服务器压力大
- 存在单点登录失败的可能性
Json Web Token :Json 令牌
- 用户输入用户名/密码登录,服务端认证成功后,会
返回给客户端一个 JWT。 客户端将 jwt 保存到本地,当用户希望访问一个受保护的路由或者资源的时候,需要在header中的 Authorization 字段中使用 Bearer 模式添加 JWT。
Authorization: Bearer <token>
服务端会检查header中的Authorization 中的 JWT 信息,如果合法,则允许访问。因为 JWT 内部包含了一些用户信息,因此减少了需要查询数据库的需要。
JWT通常由三部分组成
- Headers: 包括类别(typ)、加密算法(alg)
{
"alg": "HS256",
"typ": "JWT"
}
- Payload :包括需要传递的用户信息
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
- Signature: 根据alg算法与私有秘钥进行加密得到的签名字串, 这一段是最重要的敏感信息,只能在服务端解密;
HMACSHA256(
base64UrlEncode(Headers) + "." +
base64UrlEncode(Payload),
SECREATE_KEY
)
编码后JWT一般是类似这样一串文本,每部分之间有'.'间隔eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWV9.TJVA95OrM7E2cBab30RMHrHDcEfxjoYZgeFONFh7HgQ
JWT使用方式
- 1.放在cookie中,但是这种方式无法跨域
- 2.放在 header中的Authorization中
- 3.放在post请求中的特定字段中
cookie-session和JWT相同点和不同点
相同点
- 鉴权: 都能做到鉴权
不同点
状态: JWT是无状态的,cookie-session是有状态的,所以cookie-session更加消耗服务器内存和性能; 基于这点 JWT的扩展性> cookie-session; 并且cookie-session需要定期清理跨域: cookie-session是基于cookie的,所以不支持跨域(ps: 子域名可以访问父域名); 而JWT可以不放在cookie中,所以支持跨域;所以前端移动端都可以使用JWT这种鉴权方式
当然如果cookie-session也能做到跨域,使用
独立的缓存服务器存储sessionid-session即可,不过这样又增加的服务器消耗
- JWT一旦颁发就只能等到它过期,在这之间都是有效的; JWT如果密钥被盗,那将是很危险的,所以不能用明文传输,使用https
OAuth(开放授权)
OAuth(开放授权)是一个开放标准,允许用户授权第三方网站访问他们存储在另外的服务提供者上的信息,而不需要将用户名和密码;日常的第三方登录就是这种形式;目前已经是OAuth 2.0了;
OAuth(开放授权)步骤
- 1.通过
三方登录(授权)入口,向用户请求授权 - 2.三方登录成功后返回一个
用户凭证Code - 3.通过
用户凭证Code,向授权服务器请求Access Token - 4.授权服务器同意授权后,
返回一个资源访问的凭证(Access Token) - 5.凭证(Access Token)向资源服务器请求相关资源
- 6.资源服务器验证凭证(Access Token)通过后,将第三方应用请求的资源返回
鉴权总结
- cookie是协议解决无状态的机制
- session是常用解决无状态的机制, session基于cookie
- JWT是针对
API请求关键信息对称加密的验证方案, 是无状态的
扩展
单点登录(single sign on: sso)
一个大型系统里可能包含 n 多子系统,用户在操作不同的系统时,需要多次登录,很麻烦,单点登录就是用来解决这个问题的,在多个应用系统中,只需要登录一次,就可以访问其他相互信任的应用系统。