在说Token之前,先简单说一下什么是Session和Cookie。首先我们要知道HTTP请求是无状态的;无状态意味着:每个请求都是独立的;每个请求不会被之前的请求影响,也不会影响后面的请求;例如,当我们登录一个系统时,在验证了用户名和密码后,在打开系统的各个页面时都不需要登录,直到我们主动注销或者超时后注销;为了让服务器具有“记忆功能”,我们??可以使用Session和Cookie。01.Cookie是一种在客户端(浏览器)保存用户信息的机制;cookie由服务器生成并发送给浏览器,浏览器将cookie以键值对的形式保存在客户端的某个目录下;不同浏览器的存储大小会有一些差异,一般不超过4KB;下一次请求时,会向服务器发送cookie,服务器会分析cookie中的信息,进行身份验证。比如你进了一个公司,他们会给你一张工作卡,上面写着你的姓名、工号、部门等信息。进入工作场所,凭工作卡进出。但是cookies不能跨域名使用;就好比我拿着我们公司的工卡去你们公司,保安肯定不让进。02.Session保存在服务器端,可以用来记录客户状态;比如我们经常用Session保存客户的基本信息、权限信息等;用户第一次登录后,服务器端会创建一个Session并将SessionID返回给Browser,浏览器通常会写入Cookie中,这种Cookie也称为SessionCookie,当浏览器再次访问时,只需要使用SessionID从服务器查找Session。另外,这个SessionID不一定要保存在cookie中,但是对于浏览器客户端来说,大家默认的做法是放在cookie中。03.Cookie和Session关于Cookie和Session的区别,很多同学会回答:“Cookie保存在客户端,Session保存在服务器端”。其实这个想法并不全面:Cookie是一个实际的东西,一个很具体的东西是一段数据,而Session是一个抽象的概念,或者叫模式方法,有很多种实现方案;比如Tomcat的实现方式:在服务器端保存状态,然后生成一个JSESSIONID放到cookie中;request之后在server端用JSESSIONID查询验证状态。04.Token当然,随着用户数量的增加,服务器上存储的session数量也随之增加,这对服务器造成了很大的压力,而如果程序部署在集群或者分布式的情况下,同一个用户将请求访问A服务器并创建了一个Session,但是第二次请求是发送给B服务器的,但是B服务器上没有之前创建的Session;这就是分布式架构中的Session共享问题。为了解决这个问题,我们可以在服务器之间同步session,或者干脆把session保存在第三方组件中,比如redis;但无论采用哪种方案,session都会成为项目的负担。这个时候服务端就会想,如果这里不保存Session该多好,第一时间把用户名和密码发给我,我验证通过后给你通行证,客户端就可以了在未来的通行证中,每次请求都要带上这个;这个pass就是token,当然验证结果需要包含client信息,服务器需要知道是谁发出的请求;它还需要包括时间信息,因为通行证不可能永远有效;通行证不能是明文,否则有被拦截的风险。HMAC-SHA1:token=user_id|expiry_date|HMAC(user_id|expiry_date,k)AES:token=AES(user_id|expiry_date,x)RSA:token=RSA(user_id|expiry_date,privatekey)05.SSO单点登录一些公司将建立统一的登录系统(单点登录)。客户端先到本系统获取Token,验证通过后使用这些Token访问其他系统;APIGateway也可以提供类似的功能。我们公司就是这样。客户端访问此时先从网关获取Token,验证通过后才能访问授权接口,一段时间后必须重新设置Token。06.Token和Session对于session和token,它们没有本质的区别。两者都是加密字符串,可用于身份验证。当然,token和session还是有一些区别的。比如token跨域更容易,token更好控制等等。另外,在授权场景中,token比session有更大的优势;比如我开发一个允许微信用户登录的网站,使用token的过程大致是这样的:登录网站时,跳转到微信登录页面;用户输入用户名和密码登录微信后,给我们一个token;用户可以在我们的网站上使用令牌,我们的网站不需要知道您的微信用户名和密码。总之,如果是同一个网站,token和session区别不大。如果使用跨站,token会更方便。Cookie、Session、Token的介绍就到这里。有问题可以加我微信或者加微信群,一起讨论。
