一、cookie、session、token的了解
1、cookies: 位于浏览器(客户端),用来存储用户信息(key-value)
使用:用于响应头和请求头中,由服务器在响应头中设置,客户端保存,在发送请求头时带上cookie
优点:因为http是无状态的,利用cookie可以保存客户相关信息和状态。
缺点:
a、客户端保存,因此可能被修改,而且在传递的时候容易被人拦截(一些重要信息需要通过加密传输,而用session可以把用户相关信息和状态保存在服务器,避免信息外泄),具有安全隐患。
b、在某些浏览器中能保存的cookie数量和大小有限制
c、不支持跨域访问。
2、session: 会话,创建于服务端,用来存储用户信息(维持一个hash表,key-value形式)
使用: 一个用户对应一个session,每个session都有它独一无二的sessionid,sessionID随着响应头set-cookie保存到客户端的cookie中,客户端发送请求时带上cookies,服务器从cookies中拿到sessionID,然后根据sessionID从内存中找到对应用户的session获取用户信息
有效期: 默认30分钟超时
优缺点: 能解决cookie的隐患,但是因为保存在服务器内存中,当用户过多时,内存占用严重,性能会受到影响。可扩展性差,当具有分布式或者负载均衡的场景时,sessionid不会保证在所有服务器上同步
3、token: 访问令牌->一个服务端生成的独一无二的字符串
组成: 登录时服务器生成,一般组成为uuid(用户唯一身份标志)+time(时间戳)+sign(签名,=uuid+time+salt根据hash算法生成的字符串)+[常用的固定参数(可选)]
使用: 服务器生成后随着http响应保存在客户端的cookies或者local storage中,随着客户端请求发送到服务器,用于单点登录的身份验证,防止跨站点请求伪造等
有效期: 默认7天,用户退出时自动销毁token
优缺点: 支持跨域访问,防止信息外泄,可以在多个服务间共享。避免了session内存占用不合理的问题。
二、用户认证的两种常用方式
1、基于session的用户认证
流程如下:
a、用户输入登录信息
b、服务器验证信息是否正确,并创建一个session,然后将其存储在数据库里
c、服务器为用户生成一个sessionID,将具有sessionId的cookie放在用户浏览器里。
d、在后续请求,根据数据库验证sessionID,如果有效,接受请求
e、一旦用户注销应用程序,会话将在客户端和服务器端都被销毁
2、token验证(jwt)
a、用户输入登录信息
b、服务器验证信息是否正确,并返回已签名的token
c、token存储在客户端,例如local storage或者cookie中
d、之后的http请求都将token添加到请求头里
e、服务器解码jwt,并且如果令牌有效,接受请求
f、一旦用户注销,令牌在客户端被销毁,不需要和服务器进行交互一个关键是,令牌是无状态的,后端服务器不需要保存令牌或者当前session的记录。
三、JWT(json web token)介绍
jwt:为了在网络应用环境间传递声明而执行的一种基于json的开放标准(RFC7519)。
因为http的访问是无状态的,客户端的请求到了服务端处理后无法返回给原来的客户端,因此需要对访问的客户端进行一个识别。常用的就是利用session机制,就是上面提到的session使用的内容。
session的优缺点上面已经提到了,另外再补充两个定义:
CORS(跨域资源共享): 当我们需要让数据跨多台移动设备上使用时,跨域资源的共享会是一个让人头疼的问题,在使用ajax抓取另一个域的资源就会出现禁止请求的情况
CSRF(跨站请求伪造): 用户在访问银行网站时,很容易收到跨站请求伪造的攻击,并且能够被利用其访问其他的网站。
1、Json web token是怎么做的?
使用基于token的身份验证方法,在服务器不需要存储用户的登录记录,大致流程是这样:
a、客户端通过用户名和密码登录服务器;
b、服务端对客户端身份进行验证;
c、服务端对该用户生成token,返回给客户端
d、客户端将token保存到本地浏览器,一般保存到cookie中
e、客户端发起请求,将token放在头部
f、服务端收到请求后,首先验证token,之后返回数据
2、Json web token的组成
实际就是一个字符串,包含三部分:头部header,载荷payload,签名signature
a 、头部:json数据,描述JWT的元数据
{
'type':'JWT',
'alg':'HS256'
}
alg表示签名的算法,默认是HMAC SHA256;typ属性表令牌类型(token类型),JWT统一写JWT。
通过Base64URL算法编码生成字符串A
b、载荷:json对象,存放实际传输的数据,不存放敏感数据
{
'iss':'签发者',
'sub':'面向的用户',
'aud':'接收方',
'exp': '过期时间',
'iat': '创建时间',
'nbf': '在什么时间之前,该Token不可用',
'jti':'Token唯一标识'
}
通过Base64URL算法编码生成字符串B
c、签名signature:对前两部分的签名,防止数据篡改
需要指定一个密钥secret(也是一个字符串)。这个密钥只有服务器指定,使用header里面指定的签名算法进行加密
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
算出签名C,将header和payload用Base64URL算法对象序列化,生成的token组成就是A.B.C这种形式。
jwt的内容在发起请求时,将其放进请求头里面,一般都是Authorization字段.