在网上搜了一圈发现没啥文章讲的特别清楚,花了一点时间梳理了一下这三者的关系。自己也是小白,这篇文章对于初学只知道名词的小白可能会有所帮助。
这三者都可以解决登录认证的问题。具体而言,个人理解cookie是在本地存放服务端返回的数据的工具,session和token都属于登录验证的机制。
for cookie,验证完用户信息,服务端返回含有set-cookie字段(字段中保存了已认证的信息,如authed=true
)的响应报文后,客户端在每次请求时在头部带上cookie(如上文提到的authed=true
,服务端可以通过这个来确认你已经登陆,按照登录用户的权限进行处理)就可以认证登录。
但是这样一来,很明显,cookie有被篡改的风险,我只要把自己的cookie篡改成authed=true
不就可以了?
因此通过给Cookie添加签名(在authed=true
后加字符),服务端验证后面的签名来知道Cookie是否被篡改。
但是问题又特喵的来了,因为Cookie是明文传输的, 只要服务器设置过一次authed=true|xxxx
我不就知道true
的签名是xxxx
了么, 以后就可以用这个签名来欺骗服务器了。(我自己有个问题哈,既然这里假设可以知道签名是xxx,那么下文的session id不也是可以知道的么?这里是根据参考写的)因此Cookie中最好不要放敏感数据。 一般来讲Cookie中只会放一个Session Id,而Session存储在服务器端,这样就避免了Cookie中存放敏感数据。
好家伙,那这个session是咋用的呢?
验证完用户名和密码后,生成相应的session id,并把这个用户对象和session id一起存储在服务端, 敏感数据(比如authed=true
)都存储在这个用户对象中。接着设置Cookie中含有session id=xxxx,并对其签名,发送这一响应报文。
如此一来,用户就接收不到敏感数据了,并在此后的请求中发送Cookie给服务端。服务端收到请求后发现session id,接着进行签名认证,如果通过则从服务端取出对应的用户对象。
这一过程相当于在HTTP协议之上,通过Cookie实现了持久的会话。这个会话便称为Session。
但是搞这个session呢服务端压力会比较大——同时有很多人访问的话需要维护许多session id,所以他们又想了一个token来方便(仍旧用到cookie作为工具)。
token的原理是,给登录了的用户发令牌(token),里面包含了他的user id(数据部分),服务端对数据部分进行签名。所以token令牌=数据+签名。服务端并不保存这个token,他只是在每次收到请求时进行验证:再对数据进行一次签名,与token中的签名比较,如果相符则通过user id取到相关信息,不符?那就sorry,告诉用户你没验证通过。
如此一来,服务端就彻底实现无状态。这是使用对签名进行计算比较的时间换了存放session id的空间。