1. Web登录的本质

由于HTTP是无状态协议,所以服务端需要记录用户状态时,就需要某种机制来识别具体的用户,这个机制就是Session

2. cookie和Session

常用的会话跟踪技术是cookie和session
cookie是存储在客户端,session是存储在server端
可以说,cookie是一种补足http协议无状态的机制

一个cookie的设置分为4步

  • 客户端发送http请求
  • 服务器响应http请求 set-cookies response
  • 客户端发送http请求 包含cookie头部 发送到服务器端
  • 服务器返回一个http response

session 是用服务器来保持状态的。专门为用户开辟存储空间,session被创建后会保存在服务器中,其中session ID则发送给客户端,客户端下次发送请求携带session ID,服务器则会查询该ID 找到对应的session读取信息。

在使用session机制保持持久化登陆的实现上可以将sessionID保存在 cookie、header、URL中,客户端带着sessionID过来,服务器根据这个sessionID判断是否存在当前会话。

所以, Session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中。
Cookie是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现Session的其中一环。

3. 从Session到token

Session的问题在于,扩展性不好。如果是服务器集群,或跨域的服务导向架构,就要求session数据共享,单点登录。服务器需要保存并管理所有人的session id, 这是一个巨大的开销。可以不保存这些Session ID吗?

比如,对数据做一个签名。用HMAC-SHA256算法,加上一个只有我知道的密钥,对数据做一个签名,把这个数据和签名一起作为token,由于密钥别人不知道,就无法伪造token了。

这个token服务器不保存,只有小F把token发过来的时候,再用同样的HMAC-SHA256算法和同样的密钥,对数据再计算一次签名,和token中的签名做比较.如果相同,我们就知道小F已经登录过了,并且可以直接去到小F的user id。如果不相同,数据部分肯定被人篡改过,就可以告诉发送者: 对不起,没有认证。

这样一来,服务器就不保存session id了,它只是生成token, 验证token,用CPU的计算时间换取了session的存储空间。

3. JWT

JWT(JSON Web Token)是目前最流行的跨域认证解决方案。

JWT大致长这样,它是一个很长的字符串,中间用.分隔成三部分。JWT不仅用于认证,也可以用于交换信息。有效使用JWT,可以降低服务器查询数据库的次数。

1
Header(头部).Payload(负载).Signature(签名)

3.1 Header

Header描述JWT的元数据, alg表示签名的算法,默认是HMAC SHA156。 typ表示这个token的类型,统一写为JWT

1
{ "alg": "HS256", "typ": "JWT"}

3.2 Payload

Payload用于存放实际需要传递的数据。JWtT规定了7个官方字段。除了官方字段,你还可以定义私有字段,JWT默认是不加密的,所以不要把秘密信息放在这里。

1
2
3
4
5
6
7
iss (issuer):签发人
exp (expiration time):过期时间
sub (subject):主题
aud (audience):受众
nbf (Not Before):生效时间
iat (Issued At):签发时间
jti (JWT ID):编号

3.3 Signature

Signature是对前两部分的签名。

4. OAuth

OAuth 是一个关于授权(authorization)的开放网络标准。OAuth在“客户端”与“服务提供商”之间,设置了一个授权层。“客户端”登录授权层以后,获取token,“服务提供商”根据token的权限范围和有效期,向“客户端”开放用户储存的资料。OAuth有以下几种常用模式:

4.1 Resource Owner Password Credentials Grant(资源所有者密码凭据认可)

小A直接提供用户名和密码,让”信用卡管家”向“网易认证中心”请求token。

4.2 Implicit Grant(隐式许可)

小A用网易账号登录,确认授权后,会重定向到“信用卡管家”网站,同时捎带一个token。信用卡管家就可以用这个token,来访问网易开放的资源。

4.3 Authorization Code Grant(授权码许可)

小A用网易账号登录的时候,网易认证中心不直接发token,而是发一个授权码(authorization code)。当“信用卡管理中心”取到这个code以后,在后台再次访问网易认证中心,这一次才拿到了真正的token。

授权码模式是功能最完整,流程最严密的授权模式。

4.4 解析jwt

参考资料