在网站应用中,由于 HTTP 协议是无状态的,识别不同用户的主要方法是通过 Cookie,即用户在认证后发送它让浏览器存储,之后每一次请求中再附带这个请求头信息发回服务器,这样服务器便知道是哪位用户发出的请求。
具体实现方法有哪些呢?下面我将为大家介绍几种常见的通过 Cookie 来识别不同用户的方法。
第一类:信息存用户侧
第一类的方法是将用户的部分信息存在浏览器的 Cookie 中(如用户 ID)。那么首要问题就是要防止被人为修改,因此实现方法有两种。
方法一:Base64 数据 + HMAC
首先,我们需要理解 HMAC。
HMAC,即使用哈希算法的消息认证码,简单来说就是使用密钥(准确来说是盐 salt)给数据上一个签名。
由于哈希算法是公开的,所以需要加上一段独一无二的密钥进行签名,如果没有这个密钥,几乎不可能篡改哈希值。
你也可以使用一套简易方法来自己实现消息认证码,比如如下的伪代码:
// 密钥
key = "你的密钥(盐)"
// 消息
msg = "一些数据"
// 使用 SHA256 算法进行签名
sha256(msg + key)
// 输出省略
这样把密钥附加到消息后面,就实现了简单的消息认证码签名。但是还是建议使用现有的 HMAC
算法进行签名。
目前推荐哈希算法使用 SHA-2
系列,具体的有 SHA-224 SHA-256 SHA-384 SHA-512
,也许你听说过 MD5
,但 MD5
算法已被证明存在碰撞不再安全,SHA-1
也正在被逐渐淘汰,所以直接使用 SHA-2
即可。
接下来,应当使用 Base64
对数据本体进行编码,这么做并不是确保数据安全,因为 Base64
仅仅是一种公开编码规范,并没有加密,主要是确保数据中不会出现违反 HTTP
规范的字符导致出错。
整体流程如下:
- 用户登录,服务器已验证用户身份。
- 服务器将用户信息进行
Base64
编码。 - 服务器将 Base64 编码后的用户信息使用密钥(盐)进行
HMAC
签名。 - 将这两个信息与响应同时发送给用户,使用
Set-Cookie
响应头让浏览器自动设置Cookie
。 - 用户下次请求时,浏览器将会自动将这两个信息发送回来,服务器再次使用相同算法计算用户数据哈希值,与用户发回的签名进行对比,如果一致则说明数据未被篡改,这样就验证了用户的身份。
光看文字可能不好理解,接下来使用伪代码进行解释:
userData = {
"uid": 1,
// 建议始终写入这个过期时间数据,防止 Cookie 有效期被篡改导致无限登录
"expireAt": "2021-05-20 00:00:00"
}
// 密钥,密钥生成请使用密码学上的随机数生成器,不要人为指定,建议不少于 16 个字节
secretKey = "这是你的密钥,不要泄露"