前后端分离中session问题的处理与设计
1、问题描述
由于之前的项目都不是前后端分离的项目,cookie和session的处理也是较为简单的。而这次开发的项目是前后端分离并且采用vue+springboot技术实现,在实现登录功能的时候突然想到该怎么实现维护用户的状态信息。这里就记录一下相关的知识点概念以及我的解决方案,仅供参考。
2、cookie、session和token介绍
Cookie
和Session
都是用于在Web应用中存储数据的机制,但它们的实现方式和作用有所不同。
2.1、cookie介绍
2.1.1、什么是cookie
Cookie
是一种在Web浏览器和Web服务器之间传递的小文件,用于存储用户的一些状态信息,如登录信息、用户偏好等。当用户访问一个网站时,网站会将一个包含Cookie
信息的HTTP
响应头发送给浏览器,浏览器将这些Cookie
保存在用户的本地计算机上,下次用户访问该网站时,浏览器会自动将这些Cookie
发送给服务器,服务器据此来识别用户。
2.1.2、cookie特点
Cookie
是存储在客户端的小文件,通常大小不超过4KB;Cookie
可以通过设置过期时间来控制其有效期;Cookie
可以在服务器端和客户端之间传递数据,但是数据会明文存储在客户端上,存在安全隐患;Cookie
受浏览器的限制,不同浏览器对Cookie
的数量和大小有不同的限制。
2.1.3、cookie原理
Cookie
是通过设置HTTP响应头中的Set-Cookie
字段来创建的,浏览器会自动将这些Cookie
保存在用户的本地计算机上,并在下次用户访问该网站时将这些Cookie
发送给服务器。
- 服务器发送Cookie
当用户第一次访问一个网站时,服务器会在HTTP响应头中设置
Set-Cookie
字段,该字段包含了一个Cookie
的名称、值、过期时间、作用域等信息。 - 浏览器保存Cookie
浏览器收到服务器发送的
Set-Cookie
字段后,会将这些Cookie
保存在用户的本地计算机上。浏览器根据服务器发送的Set-Cookie
字段中的过期时间来决定Cookie的有效期,如果没有设置过期时间,则默认为当前会话期间。 - 浏览器发送Cookie
当用户再次访问该网站时,浏览器会自动将保存在本地的
Cookie
发送给服务器。浏览器会在HTTP
请求头中设置Cookie
字段,该字段包含了所有与该网站相关的Cookie
信息。 - 服务器处理Cookie
服务器收到浏览器发送的
Cookie
后,会将其解析出来,并根据Cookie
中的信息进行相应的处理。服务器可以使用Cookie
来识别用户、存储用户偏好等信息。
2.2、session介绍
2.2.1、什么是session
Session
是一种在Web应用服务器端维护用户状态的机制,用于存储用户的一些状态信息,如登录信息、购物车内容等。当用户访问一个网站时,网站会在服务器端创建一个Session
,并分配一个唯一的Session ID
,将这个Session ID
通过Cookie
等方式传递给客户端浏览器,下次用户访问该网站时,浏览器将这个Session ID
带回服务器端,服务器据此来识别用户。
2.2.2、session特点
Session
是存储在服务器端的,通常会存储在内存或者数据库中,因此相对于Cookie更加安全;Session
可以通过设置过期时间来控制其有效期;Session
可以存储比Cookie
更大的数据量;Session
对客户端没有大小限制,因为只有一个Session ID
存储在客户端中。
需要注意的是,Session
和Cookie
都可以用于存储用户状态信息,但它们的实现方式和使用场景不同。在一些安全性要求较高的场景下,Session
会更加适合。在需要跨域共享数据的场景下,Cookie
会更加适合。
2.2.3、session原理
- 创建Session
当用户第一次访问一个网站时,服务器会为该用户创建一个
Session
,并生成一个唯一的Session ID
。Session ID
可以通过Cookie
等方式传递给客户端浏览器,以便下次用户访问该网站时能够自动识别该用户。 - Session ID传递
服务器将
Session ID
传递给浏览器,通常是通过Cookie
方式来传递。服务器会在HTTP响应头中设置Set-Cookie
字段,该字段包含了Session ID
等信息。 - 浏览器发送Session ID
当用户再次访问该网站时,浏览器会自动将保存的
Session ID
发送给服务器。浏览器会在HTTP
请求头中设置Cookie
字段,该字段包含了保存的Session ID
等信息。 - 服务器处理Session
服务器收到浏览器发送的
Session ID
后,会根据Session ID
来查找相应的Session
。服务器可以使用Session
来存储用户的登录信息、购物车内容等状态信息,以便下次用户访问该网站时能够继续使用这些状态信息。
2.3、token介绍
Token
是一种基于加密算法的安全字符串,用于表示用户身份和权限信息。在Web应用中,Token通常被用来维护用户状态信息。
2.3.1、token工作原理
- 用户登录
用户在客户端输入用户名和密码后,客户端会将该信息发送给服务器。服务器会验证用户信息,如果验证成功,则会生成一个
Token
并将其返回给客户端。 - Token生成
服务器在生成
Token
时,会使用一种加密算法对用户信息进行加密,并将加密结果作为Token
。加密算法可以是对称加密或非对称加密。对称加密算法需要服务器和客户端之间共享一个密钥,而非对称加密算法则需要服务器和客户端之间各自拥有一对公私密钥。 - Token传递
客户端浏览器会保存
Token
,并在后续的请求中将Token
以某种方式传递给服务器,例如在HTTP
请求头中添加Authorization
字段,或者在请求参数中添加Token
参数等。 - Token验证
服务器在接收到客户端的请求后,会验证
Token
的有效性,以确认该请求是否是合法的。Token
验证的方式可以是对称加密解密或非对称加密解密。对称加密算法需要服务器使用密钥对Token
进行解密,而非对称加密算法则需要服务器使用私钥对Token
进行解密。 - Token过期处理
服务器可以设置
Token
的过期时间,以便保证Token
的安全性。如果客户端浏览器保存的Token
已经过期,则需要重新登录以获取新的Token
。
3、前后端分离项目维护用户状态信息
在前后端分离的项目中,通常会使用token
来管理用户的身份认证和授权,而不是传统的Session
机制。Token是一种基于加密算法的安全字符串,用于表示用户身份和权限信息。通常,服务器会在用户登录成功后生成一个Token
,并将其返回给客户端浏览器,以便客户端在后续的请求中带上该Token
来识别用户身份。
3.1、前后端分离不推荐session的原因
- 分离了前后端的职责
前后端分离的项目中,后端只负责提供
API
接口,不再涉及页面渲染等操作,因此不需要使用Session
来维护用户的状态信息。前端通过调用后端API
来获取数据,后端根据前端传递的Token
进行用户身份验证,并根据Token
中携带的用户信息来返回对应的数据。 - Session数据难以分布式管理 在分布式系统中,多个服务器之间需要共享Session数据,需要进行相应的同步和管理。这增加了系统的复杂性和开发难度。
- Session容易引发跨域问题
使用
Session
来维护用户状态时,需要将Session ID
存储在Cookie
中,但是Cookie
会受到浏览器的限制,容易引发跨域问题。 - 增加了系统的开销
使用
Session
需要在服务器端存储Session
数据,增加了服务器的负担。如果是高并发系统,这些开销会更加明显。 - 不易扩展
使用
Session
方式维护用户状态时,随着业务的增长,Session
中存储的信息也会不断增加,这会导致Session
数据量变大,不易扩展。 综上所述,前后端分离的项目中,推荐使用Token
来维护用户的状态信息,而不是Session
。Token
具有轻量级、无状态、易扩展等优点,更适合前后端分离的开发模式。
3.2、前后端使用token步骤
- 用户登录
用户在客户端输入用户名和密码后,客户端会将该信息发送给服务器。服务器会验证用户信息,如果验证成功,则会生成一个
Token
并将其返回给客户端。 - Token传递
客户端浏览器会保存
Token
,并在后续的请求中将Token
以某种方式传递给服务器,例如在HTTP
请求头中添加Authorization
字段,或者在请求参数中添加Token
参数等。 - Token验证 服务器在接收到客户端的请求后,会验证Token的有效性,以确认该请求是否是合法的。如果Token验证成功,则会处理该请求并返回相应的结果;如果Token验证失败,则会拒绝该请求,并要求客户端重新进行登录。
- Token过期处理
服务器可以设置
Token
的过期时间,以便保证Token
的安全性。如果客户端浏览器保存的Token
已经过期,则需要重新登录以获取新的Token
。
使用Token
来维护用户状态信息的优点是,相对于传统的Cookie
和Session
机制,Token
更加安全和灵活,可以避免一些安全隐患,并且支持跨域和跨平台的应用场景。但是需要注意的是,开发者需要合理地设计Token
的生成算法和验证机制,以确保其安全性和可靠性。同时,服务器应该保护好密钥的安全,避免密钥被泄露导致Token
被盗用。