http协议是无状态的。每一个request请求时没有记忆力。
方式一: 传统session:
step1: client登录,server据user信息生成一个token,并保存token和对应的user_id到db or session中,接着把token传回给client,存入浏览器cookie;
step2: 浏览器请求带着cookie,后端根据cookie值查询user 验证是否过期;
缺点:1.xss漏洞,由于cookie可以被js读取,token会泄露!用户信息不再安全!
2.csrf跨站请求伪造;
3.验证信息存储到db中,每次根据token查询id,增加db开销!而把验证信息存储到session中,则增加服务器端存储压力!
方式二: jwt(json web token)方式:
jwt组成:
1.header:
{
"alg": "HS256",
"typ": "JWT"
}
把这个用base64编码成jwt的第1个“零件”;
2.payload:
{
"iss": "签发者,例如 telangpu",
"iat": "签发时间,例如1441593502",
"exp": "过期时间,例如1441594722",
"aud": "接收方,例如www.cctv.com",
"sub": "面向的用户,例如telangpu@163.com",
}
把这个用base64编码成jwt的第2个“零件”;
3.signature
signature是需要用前面生成的2个零件(base64编码后的header和payload)以及一个秘钥,采用header中指定的签名算法(HS256)签名。 为啥签名?因为防篡改!!!
最后用 "零件1.零件2.signature"的格式形成了jwt:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJpZCI6IjU3ZmVmMTY0ZTU0YWY2NGZmYzUzZGJkNSIsInhzcmYiOiI0ZWE1YzUwOGE2NTY2ZTc2MjQwNTQzZjhmZWIwNmZkNDU3Nzc3YmUzOTU0OWM0MDE2NDM2YWZkYTY1ZDIzMzBlIiwiaWF0IjoxNDc2NDI3OTMzfQ
.PA3QjeyZSUh7H0GfE0vJaKW4LjKJuC3dVLQiY4hii8s
思考和复盘:
签名目的:对header和payload签名防止内容被篡改。篡改后的新jwt签名对不上!
信息暴露: base64仅仅是编码!可逆! 是的!所以payload中的信息不加敏感数据!不放密码啥的!
方式一 VS 方式二
session存储id 弊端在于session需要server存储! KV数据库和缓存机制;
jwt方式把用户状态分散到client中,减轻了server内存压力;
单点登录。对于多站点的多个机器来说,jwt完胜。