Cookie,Session和Token详解
1.Cookie
Cookie由Server生成,返回给浏览器,浏览器以key-value的格式保存的自己的目录下,下一次再请求Server时,把Cookie发送给Server。
Cookie主要缺点:
1.用户使用浏览器时,可以禁用Cookie,影响性能;
2.Cookie数据是暴露的,需要加密避免暴露;
3.浏览器端保存的数据量有限制,每个Cookie限制的大小是4KB,浏览器一般保存300多个Cookie,每个网站保存20个Cookie。
2.Session
Session的主要原理是给客户端一个唯一身份标识(即session_id),并将这个session_id和客户端信息保存在Server端,当客户端再次访问Server时,请求中带上这个唯一标示(客户端可以使用多种方式保存session_id,一般使用Cookie),这样Server就知道是哪个客户端的请求了。
Session主要缺点:
1.如果Server端是多机服务,要考虑Session信息可以服用,一般采用缓存服务器保存session或者客户端的session有效期内的请求都绑定到同一台机器上。
3.Token
Token主要解决Client连接Server时,每次都要进行用户和密码的验证的问题,其主要过程如下:
1.Client使用用户名和密码登陆Server;
2.Server收到Client的请求,Server验证用户名和密码;
3.Server验证成功后,Server签发一个token,然后将token返回给Client;
4.Client收到token后保存到本地(Client可以使用多种方式保存token,一般使用Cookie);
5.Client再次向Server发送请求时,带上Server签发的token;
6.Server收到Client的请求和token后,验证用户和token,如果成功就返回响应结果,否则拒绝访问。
4.JWT(Json Web Token)
JWT是一个基于JSON格式的开放式token标准,主要用于身份认证,信息安全交换,保持http协议的记录状态,并解决跨域认证的问题。
JWT的结构:
Header.Payload.Singature
4.1 头部Header
Header主要包含令牌的类型和算法。
{
"alg":"HS256", // 即HMAC SHA256或者RS256,RS512
"typ":"JWT"
}
注意上面的JSON结构是使用Base64Url编码后保存到Header部分的。
4.1 有效载荷Payload
Payload中主要保存声明内容,即通讯信息,目前有3中声明(claims)
a.标准注册声明(Registered claims):是JWT推荐,但是不强制的声明,主要声明如下:
iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号
b.公开声明(Public claims):
公开声明可以添加任何的信息,主要满足添加用户相关的信息。
c.私有声明(Private claims):
私有声明主要为请求者和响应者之间共同定义的声明,这样满足他们单独的定制声明,这些信息不公开。
Playload示例:
{
"iss": "lance-server",
"exp": "2019-07-05 15:00:00",
"iat": "2019-07-05 14:00:00",
"sub": "lance-shopping-cart",
"userId": "1000",
"userName": "lance"
}
注意Payload默认不是加密的,不要在payload中保存敏感信息,另外Payload部分也是使用Base64Url编码保存的。
4.3 签名Signature
Signature是对Header和Payload的签名,防止数据被篡改,具体何时如下:
HMACSHA256算法:
Signature = HMACSHA256(base64UrlEncode(header)+"."
+base64UrlEncode(payload),
secret);
其中secret是Server端的密码,不公开。
RSA算法:
Signature = RSA256(base64UrlEncode(header)+
"."+base64UrlEncode(payload),
RSA private key);
RSA private key为Server端RAS密钥对中的私钥,不公开。
一个JWT示例:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
JWT官网示例.png
JWT默认是不加密的,但是可以支持加密,最好使用https以防止盗用,主要应用于认证和信息交换,降低服务器的认证代价。但是由于Server不保存token的信息,因此Server无法废止某个token,只能等到该token过期为止,而且一旦JWT被泄露盗用,任何人在过期时间内都可以获得Server的认证,因此要根据自身系统安全性的要求设置过期时间。