实现登录状态保持的方法
方法一:cookie和session配合使用
首先,用户登录输入用户名和密码,浏览器发送post请求,服务器后台获取用户信息,查询数据库验证用户信息是否正确。如果验证通过,就会创建session来存储相关信息,并且生成一个cookie字符串,把sessionID放在cookie里面。然后返回给浏览器。
当用户下一次发起请求时,浏览器会自动携带cookie去请求服务器,服务器识别后,通过里面的sessionID,就可以直接读取session中的用户信息。这样,用户就可以直接访问,不需要再输入用户名和密码来验证身份。
缺点:
cookie
容易被修改,被劫持,并不是绝对的安全- 大型项目中,服务器往往不止一台
如果第一次请求,用户信息被保存在服务器1的session
空间里。而第二次请求被分流到了服务器2,这样就获取不到用户信息,依然要重新登录。
方法二:如果cookie被禁用了,怎么保持登录状态?
保持登录的关键不是cookie
,而是通过 cookie
保存和传输的 sessionID
,其本质是能获取用户信息的数据。除了 cookie
,还通常使用 HTTP
请求头来传输,比如标准的Authorization
,也可以自定义,如 X-Auth-SessionID
等。但是这个请求头浏览器不会像 cookie
一样自动携带,需要手工处理。也可以进行url
地址重写,将sessionID
追加在url
后面
注意:
前面的cookie
和session
这种模式,没有分布式架构,无法支持横向扩展。如果使用一个服务器,该模式完全没有问题。但是,如果它是服务器群集或面向服务的跨域体系结构的话,则需要一个统一的session
数据库来保存会话数据实现共享,这样负载均衡下的每个服务器才可以正确的验证用户身份。
方法三:Token
Token
是在服务端产生的。如果前端使用用户名/密码向服务端请求认证,服务端认证成功,那么在服务端会返回Token
给前端。前端可以在每次请求的时候带上 Toke
证明自己的合法地位。如果这个Token
在服务端持久化(比如存入数据库),那它就是一个永久的身份令牌。
方法四:JWT(JSON Web Token)
什么是JWT?
JSON Web Token(JWT)
是一个开放式标准(RFC 7519),它定义了一种紧凑且自包含的方式,用于在各方之间以JSON
对象安全传输信息。这些信息可以通过数字签名进行验证和信任。可以使用秘钥(使用HMAC
算法)或使用RSA
的公钥/私钥对对JWT
进行签名。
为什么使用JWT?
随着技术的发展,分布式web
应用的普及,通过session
管理用户登录状态成本越来越高,因此慢慢发展成为token
的方式做登录身份校验,然后通过token
去取redis
中的缓存的用户信息。随着之后JWT
的出现,校验方式更加简单便捷化,无需通过redis
缓存,而是直接根据token
取出保存的用户信息,以及对token
可用性校验,单点登录更为简单。
JWT的优点:
- 体积小,因而传输速度更快
- 多样化的传输方式,可以通过
URL
传输、POST
传输、请求头Header
传输(常用) - 简单方便,服务端拿到
jwt
后无需再次查询数据库校验token
可用性,也无需进行redis
缓存校验 - 在分布式系统中,很好地解决了单点登录问题
- 很方便的解决了跨域授权问题,因为跨域无法共享
cookie
JWT的缺点:
- 因为
JWT
是无状态的,因此服务端无法控制已经生成的Token
失效,这是不可控的 - 获取到
JWT
也就拥有了登录权限,因此JWT
是不可泄露的,网站最好使用https
,防止中间攻击偷取JWT
实现方式:
JWT
的原则是在服务器身份验证之后,将生成一个JSON
对象并将其发送回用户;- 之后,当用户与服务器通信时,客户端在请求中发回
JSON
对象。服务器仅依赖于这个JSON
对象来标识用户。为了防止用户篡改数据,服务器将在生成对象时添加签名 - 服务器不保存任何会话数据,即服务器变为无状态,使其更容易扩展。
Token和JWT的区别
相同:
- 都是访问资源的令牌, 都可以记录用户信息
不同:
- 服务端验证客户端发来的
token
信息要进行数据的查询操作 JWT
验证客户端发来的token
信息就不用, 在服务端使用密钥校验就可以,不用数据库的查询。
cookie和token都存放在header中,为什么不会劫持token?
token
不是为了防止XSS
的,而是为了防止CSRF
的;CSRF
攻击的原因是浏览器会自动带上cookie
,而不会带上token
;
CSRF
就是利用的这一特性,所以token
可以防范CSRF
,而cookie
不能。JWT
本身只关心请求的安全性,并不关心token
本身的安全。