权限的控制机制
说到了登陆,那么我们会联想到权限的控制,决定用户登陆后的一些访问以及控制的权限。谈到权限的控制机制,目前使用的有Session,Token,JWT(JSON Web Token),oauth2.0等等。
(1) Session
对比起 Cookie,Session 是存储在服务器端的会话,相对安全,并且不像 Cookie 那样有存储长度限制,由于 Session 是以文本文件形式存储在服务器端的,所以不怕客户端修改 Session 内容。
通过session认证登陆的一个流程:
- 用户向服务器发送账户和密码。
- 服务端进行验证通过后,在当前对话(session)里保存关键数据,比如登陆用户的信息、权限等等。
- 服务端向用户返回一个session_id, 写入用户的Cookie。
- 随后,用户的每次请求,都会通过Cookie的session_id传送回服务器。
- 服务端收到session_id之后,查询之前保存的相关数据,就可得知用户的身份与权限。
在单体应用下,这种认证登陆以及权限的控制方式,基本没什么问题。
而在集群服务,也就是部署到多台服务器的状况下,使用Session进行登录后的权限控制流程大概如下:
在分布式架构的情况下,几台服务器的session是无法共享的,所以采用了复制session信息的方法,复制到另外几台的服务器上。这种方法会造成服务器的资源压力很大。也是一种缺陷。
为了解决session共享的问题,可以借用Redis持久化缓存,通过Redis集中的存储session信息。 流程如下:
(2) Token
在集群服务的情况下,我们还可以使用Token的形式,也就是服务器无状态的情况下,把服务器生成的Token存放在Redis中。Redis的数据结构是key 与 value 的形式,而此时的key可以存放Token,而Value可以存放用户登录后的UserId。而这个key和value如何存储还是取决于你自己设计。
下面是采用Token进行登录权限控制的流程:
关于密码在登录的过程,还可以采用MD5进行加密然后再进行加盐,可以确保它的安全性。
不过每次都需要通过token去查询用户的身份,对服务器的压力也是非常大的。
(3) JWT
JSON Web Token (JWT) 是一个开放标准 ( RFC 7519 ),它用于在各方之间以 JSON 对象的形式安全传输信息。此信息可以验证和信任,因为它是数字签名的。JWT 可以使用密钥(使用HMAC SHA256算法)或使用RSA或ECDSA的公钥/私钥对进行签名。
JWT的主要组成部分:
- Header 头部
- Payload 有效负载
- Signature 验证签名
1. Header 存放的数据
{
"alg": "HS256", // 加密的算法
"typ": "JWT" // jwt类型
}
2. Payload 装载的数据
{
"sub": "1234567890",
"name": "Jobin",
"admin": true
}
3. Signature 验证签名数据
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
your-256-bit-secret
)
4. JWT底层结构原理
通常我们看到的JWT是这样子的,如:xxxxxxx.yyyyyyyy.zzzzz 它们是三个用点分隔的 Base64-URL 字符串,可以在 HTML 和 HTTP 环境中轻松传递,同时与基于 XML 的标准(如 SAML)相比更相似。 该 JWT 具有先前的header(头部)和Payload(有效负载编码),并使用Signature(秘钥签名)。 也就是把上面的xxxxxxx.yyyyyyyy.zzzzz 相等于 header.payload.signature
JWT的数据是通过Base64进行编码和解码的,所以我们可以把一条JWT的数据去解码一下,看是否与之前的数据一致。
我们去JWT官方拿取Payload的数据去进行解码以及编码试试,可以从图中看出,就是一致的。也可以得出JWT的数据顺序。在JWT中的Payload数据是无法被篡改的,所以有一定的安全性。
Payload的JWT数据解码后:
5. JWT的优缺点
优点:
- 不需要在服务器存放用户的数据,减轻服务器端压力
- 是
JSON风格,轻量级、可跨语言,并且可跨域访问等。
缺点:
由于JWT生成之后是存放在客户端(浏览器)下的,当Token生成之后无法修改:
- 可以设置TLL有效时间,但是无法刷新
token有效期、无法销毁token。 token的存储占位较大。