web中的使用
http的无状态连接,断开连接后登录后保持登录状态就成了问题,所以服务器验证后就保存session在服务器端,response里返回一个cookie,可以设置过期时间等,下次发送请求带上cookie,通过jsessionid在服务器找对应的session(session里面也有保存jsessionid)
以上的带来的问题是用户量多了服务器的负担和分布式系统时的cookie共享和cookie容易被拦截篡改之类的问题发生
cookie
cookie有以下三种
会话期cookie
持久性cookie
第三方cookie
cookie是由服务器端返回的,储存在用户本地终端上的数据
服务器端通过HTTP响应报文向客户端发送Cookie,在Set-Cookie中设置需要的内容
cookie有以下属性
其中name=value是必选项,其它都是可选项。
name:一个唯一确定的cookie名称。通常来讲cookie的名称是不区分大小写的。
value:存储在cookie中的字符串值。最好为cookie的name和value进行url编码
domain:表示cookie的作用域(子域等)
path:对那些请求有效
expires/max-age:失效时间/存在时间(效果相同)
HttpOnly:防止XSS攻击(js无法读取cookie e.g.在输入框输入下面代码如果可以输出就没有加HttpOnly)
"/><script>alert(document.cookie)</script><!--
secure:cookie只能在https协议进行传输
session
session存在于服务器端存在的分布式系统中无法共享状态时可采用以下几种:
1、session 复制
2、客户端保存session(不安全)
3、固定用户访问服务器(IP hash、业务数据 hsah)
4、共享存储(redis)
JWT
json web token
JWT,解决了以上的大部分问题,分布式中可以解决http的无状态和session共享
jwt使用流程:
- 用户通过form表单完成登录后服务器端校验用户id、密码后颁发令牌通过response返回
- token是一块经过加密的令牌,可以验证你的身份,存储在本地,但是不同session和cookie的是服务器端不必存储任何信息,只需要验证令牌的正确性就行了
- 有了token分布式的服务的请求就不用担心共享状态的问题了
JWT的实现
JWT是一个由三部分组成的一串字符串是经过编码和加密的密钥
1.令牌组成
- 1.标头(Header)
- 2.有效载荷(Payload)
- 3.签名(Signature)
- JWT通常如下所示:xxxxx.yyyyy.zzzzz ==> Header.Payload.Signature
标头通常由两部分组成:令牌的类型(即JWT)和所使用的签名算法,例如HMAC SHA256或RSA。它会使用 Base64 编码组成 JWT 结构的第一部分。
默认示例:
{
"alg": "HS256",
"typ": "JWT"
}
令牌的第二部分是有效负载,其中包含声明。声明是有关实体(通常是用户)和其他数据的声明。同样的,它会使用 Base64 编码组成 JWT 结构的第二部分(Base64是可逆的)
{
"id": "123",
"name": "Test",
"root": true
}
签名由前面两部分都是使用 Base64 进行编码的,即前端可以解开知道里面的信息。Signature 需要使用编码后的 header 和 payload 以及我们提供的一个密钥,然后使用 header 中指定的签名算法(HS256)进行签名。签名的作用是保证 JWT 没有被篡改过
签名目的
最后一步签名的过程,实际上是对头部以及负载内容进行签名,防止内容被窜改。如果有人对头部以及负载的内容解码之后进行修改,再进行编码,最后加上之前的签名组合形成新的JWT的话,那么服务器端会判断出新的头部和负载形成的签名和JWT附带上的签名是不一样的。如果要对新的头部和负载进行签名,在不知道服务器加密时用的密钥的话,得出来的签名也是不一样的。