egg中间层session鉴权是怎么做的?会有什么问题?

因为egg中间件是遵循洋葱圈模型的,每一个请求都会经过中间件的一层层处理。
egg的session基于session,但是和cookie不同的是cookie保存在客户端中,session保存在服务端,相对于cookie更安全;

用户登录之后,将user信息放到session中,后端接口需要用户信息时,在中间层中加入到请求体中,不会暴露在浏览器上;

2020-10-18补充:为什么需要session鉴权?
因为http协议是一种无状态的协议,当用户提供给我们用户信息进行认证之后,下一次请求时用户还需要再次进行认证,因为http协议的无法取到上一次的用户信息,所以我们并不知道这次请求是哪个用户发出的,(传统session鉴权:)所以为了让我们能够识别是哪个用户发起的请求,需要在服务器上存储一段用户信息的token,这个token会在响应时传递给浏览器,并且告诉浏览器保存为cookie,以便于下次请求时发送给服务端,这样我们就能辨别是哪个用户了。

基于session认证暴露出来的问题:1.服务端开销大,因为每个用户经过我们的认证之后,都需要在服务端记录一次,通常都是保存在内存中,随着用户的增多,服务端开销会明显增大;2.扩展性:用户认证之后服务端做认证记录,如果认证记录被保存在内存中的话,意味着用户下一次请求还必须在这台服务器上,这样才能拿到认证信息;3.csrf:因为是基于cookie来进行用户识别,会暴露在浏览器中,cookie如果被截获,用户就会很容易受到跨站请求伪造的攻击。

2022-09-24补充:
用户认证和授权?
用户认证,指的是认证用户的身份,比如用户登录某个系统,系统需要用户输入用户名和密码来确认你真的是用户本人。
授权,指的是认证用户之后,提供给用户的对系统的某些操作权限,比如某些用户权限只能查看数据,而某些用户可以查看并且修改数据。(权限控制,RBAC模型,用户-角色-权限)

目前的主流用户认证方式有基于session和基于token两种方式。

这两种认证方式有什么区别?优缺点?
session认证的流程:

  1. 用户登录,并提交登录信息
  2. 服务端验证信息是否正确,正确则创建一个session,并存储在数据库中
  3. 服务端为用户生成一个sessionId,将含有sessionId的cookie存在客户端中
  4. 后续请求中,服务端接收到请求后会先去验证sessionId,如果有效,则接受请求
  5. 用户登出,服务端和客户端都会销毁session

token认证,jwt(JSON Web Token),是基于token的用户认证
token认证的流程:

  1. 用户登录,并提交登录信息
  2. 服务端认证信息是否正确,正确则返回已签名的token
  3. 客户端拿到token并将token存在客户端,如localStorage或Cookie中,并且之后的每次请求都将token放在请求头中
  4. 后续请求中,服务端拿到token进行解析,如果有效则接受请求
  5. 若token失效或者token错误,jwt解析会抛出错误
  6. 用户登出,客户端销毁token,可以不与服务端进行交互,因为服务端不会保存token

session认证和token认证的区别?
主要区别就是用户认证信息的保存位置,session是保存在服务端的,token是保存在客户端的。

jwt的优点:
- 1. 扩展性好,在分布式部署的情况下,session需要做多机数据共享,通常可以存在数据库或者redis中。而jwt不需要客户端存储
- 2. 无状态,jwt不在服务端中存储,RESTful API的原则之一就是无状态,发出请求时,总会返回带有参数的响应,不会产生附加影响,不会产生附加影响。

jwt的缺点:
- 1. 安全性,由于jwt的载荷使用的base64编码,没有加密,因为jwt中不能存储敏感信息,比如用户的密码等。而session是存在服务端的,相对来说更加安全
- 2. 性能,jwt太长,由于jwt是无状态的,所有的数据都放在了JWT里面,经过编码之后的jwt会非常长,而cookie限制数据大小为4kb,很可能会存不下,所以token一般放在localstorage中。而且每次请求都会携带token,可能会导致http的请求头比请求体还要大,而sessionId只是一个很短的字符串,因此使用jwt认证的http请求要比session认证的开销大。