常见的鉴权方案
- 每种鉴权方案的实现原理
- 这种鉴权方案的优缺点
- 极简的代码实现
1、HTTP Basic Authentication
实现的关键: http协议中响应头字段WWW-Authenticate和请求头Authorization
1.1、认证过程
1. 客户端向服务器请求数据,请求的内容可能是一个网页或者是一个ajax异步请求,此时,假设客户端尚未被验证,则客户端提供如下请求至服务器
2. 服务器向客户端发送验证请求代码401,并在响应头添加字段WWW-Authenticate: XXXX。 服务器返回的响应数据大抵如下
HTTP/1.0 401 Unauthorised
Server: SokEvo/1.02
WWW-Authenticate: Basic
Content-Type: text/html
Content-Length: xxx
3. 当符合http规范的客户端(如Chrome,FIREFOX)收到401返回值时,将自动弹出一个登录窗口,要求用户输入用户名和密码。
4. 用户输入用户名和密码后,客户端会将用户名及密码以BASE64加密方式加密,并将密文写入到请求头的Authorization字段当中,(浏览器自动将${username}:${passwrod}进行base64加密,并添加认证类型Basic)此时客户端发送的求信息则变成如下内容
Get /index.html HTTP/1.0
Host:www.google.com
Authorization: Basic d2FuZzp3YW5n
5. 服务器收到上述请求信息后,将Authorization字段后的用户信息取出、解密,将解密后的用户名及密码与用户数据库进行比较验证,如用户名及密码正确,服务器则根据请求,将所请求资源发送给客户端
优点: 实现简单,快捷。
缺点: 因为base64加密可逆,所以安全性极低。
2、session-cookie
第二种这个方式是利用服务器端的session(会话)和浏览器端的cookie来实现前后端的认证
标准session-cookie认证主要分为以下几步:
1,服务器在接受客户端首次访问时在服务器端创建seesion,然后保存seesion(通常保存在redis中),然后给这个session生成一个唯一的标识字符串,然后在响应头中种下这个唯一标识字符串。
2:浏览器中收到请求响应的时候会解析响应头,然后将session_id保存在本地cookie中,浏览器在下次http请求时请求头中会带上该域名下的cookie信息
3:服务器在接受客户端请求时会去解析请求头cookie中的session_id,然后根据这个session_id去找服务器端保存的该客户端的session,然后判断该请求是否合法.
缺点:
1、保存session信息需要增加服务器的开销,而且不利于扩展。
2、依赖浏览器的cookie,所以对APP等移动应用不友好。
3、依赖cookie,所以安全性隐患相对较大。
一篇很不错的session-cookie实现教程:
medium.com/@evangow/se…
3、Token
使用基于 Token 的身份验证方法,大概的流程是这样的:
- 客户端使用用户名跟密码请求登录
- 服务端收到请求,去验证用户名与密码
- 验证成功后,服务端会签发一个 Token,再把这个 Token 发送给客户端
- 客户端收到 Token 以后可以把它存储起来,比如放在 Cookie 里或者 Local Storage 里
- 客户端每次向服务端请求资源的时候需要带着服务端签发的 Token
- 服务端收到请求,然后去验证客户端请求里面带着的 Token,如果验证成功,就向客户端返回请求的数据
4、JWT原理
JWT 的原理是,服务器认证以后,生成一个 JSON 对象,发回给用户,就像下面这样。
{
"姓名": "张三",
"角色": "管理员",
"到期时间": "2018年7月1日0点0分"
}
以后,用户与服务端通信的时候,都要发回这个 JSON 对象。服务器完全只靠这个对象认定用户身份。为了防止用户篡改数据,服务器在生成这个对象的时候,会加上签名(详见后文)。
服务器就不保存任何 session 数据了,也就是说,服务器变成无状态了,从而比较容易实现扩展。
JWT 的三个部分依次如下。
Header(头部)
Payload(负载)
Signature(签名)
4.1、header
Header 部分是一个 JSON 对象,描述 JWT 的元数据,通常是下面的样子。
{
"alg": "HS256",
"typ": "JWT"
}
上面代码中,alg属性表示签名的算法(algorithm),默认是 HMAC SHA256(写成 HS256);typ属性表示这个令牌(token)的类型(type),JWT 令牌统一写为JWT。
4.2、Payload
Payload 部分也是一个 JSON 对象,用来存放实际需要传递的数据。JWT 规定了7个官方字段,供选用。
iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号
除了官方字段,你还可以在这个部分定义私有字段,下面就是一个例子。
{
"sub": "1234567890",
"name": "John Doe",
"admin": true
}
注意,JWT 默认是不加密的,任何人都可以读到,所以不要把秘密信息放在这个部分。
4.3、Signature
Signature 部分是对前两部分的签名,防止数据篡改。
首先,需要指定一个密钥(secret)。这个密钥只有服务器才知道,不能泄露给用户。然后,使用 Header 里面指定的签名算法(默认是 HMAC SHA256),按照下面的公式产生签名。
算出签名以后,把 Header、Payload、Signature 三个部分拼成一个字符串,每个部分之间用"点"(.)分隔,就可以返回给用户。
4.4、refreshToken
为了减少assessToken被盗用的风险,所以会将assessToken的有效期设置为较短。
添加refreshToken用于刷新assessToken.
特点: 1、token 使服务端无状态化,有利于扩展 2、token 也可以配合session使用。且token比cookie更为安全 3、token一旦颁发,在有效期内无法取消。除非在服务器部署特殊逻辑。
5、SSO
接下来我们探讨一个企业应一定绕不过的课题:单点登录。
在单点登录领域,CAS(Central Authentication Service,中文名是中央认证服务) 是一个被高频使用的解决方案。因此,这里介绍一下利用CAS 实现SSO。而CAS 的具体实现又可以依赖很多种协议,比如OpenID、OAuth、SAML 等,这里重点介绍一下CAS 协议。
5.1、 CAS 协议中的几个重要概念
简单介绍一下CAS 协议中的几个重要概念,一开始看概念可能很模糊,可以先过一遍,再结合下面的流程图来理解。
-
CAS Server:用于认证的中心服务器
-
CAS Clients:保护CAS 应用,一旦有未认证的用户访问,重定向至CAS Server 进行认证
-
TGT & TGC:用户认证之后,CAS Server 回生成一个包含用户信息的TGT (Ticket Granting Ticket) 并向浏览器写一个cookie(TGC,Ticket Granting Cookie),有啥用后面流程会讲到
-
ST:在url 上作为参数传输的ticket,受保护应用可以凭借这个ticket 去CAS Server 确认用户的认证是否合法
5.2 以豆瓣为例理解CAS协议
(1)第一次登陆豆瓣读书流程
- A: 浏览器请求访问 豆瓣读书。
- B: 豆瓣读书 引导浏览器 重定向 到 豆瓣用户中心。携带 Service参数
- C: 在 用户中心 完成登录,建立全局会话。
- 验证 Service
- 生成TGT
- 在浏览器记录CASTGC,即TGT.id,即 建立全局会话
- D: CAS服务器产生Service Ticket,并 重定向 到业务系统。
- 用TGT 签发 ST
- 重定向到 Service代表的 豆瓣读书 路由
- 并携带 ST
- E: 豆瓣读书 用Service Ticket 向 用户中心服务器 兑换用户信息。
- 豆瓣读书服务器获取 ST
- 豆瓣读书在后台用 ST 向 用户中心服务器 兑换用户信息,官方使用xml传输信息(本文用JSON代替)
- 兑换成功后,豆瓣读书 用Session或Cookie 记录用户的登录状态,即 建立局部会话。
(2)第二次登陆豆瓣读书流程
(3) 第一次登陆豆瓣电影流程
5.3 单点登出
实现教程:medium.com/brightlab-t…
参考文档:developers.onelogin.com/quickstart
优点:
1、提高用户效率
2、方便管理与开发