魔方功能比较多,而MVC版和API版又略有不同,这里讲一下登录以及用户鉴权机制。

登录

魔方的登录分三种:

  1. 密码登录。在登录页输入用户名密码登录,可能自定义项目配合有验证码等其它信息。
  2. SSO登录。配置OAuth后,在登录页点击跳转第三方用户中心,完成后跳转回来。
  3. 令牌登录。其它应用调用魔方OAuth接口取得令牌,或者手机验证通过了直接颁发令牌,甚至其它应用知道魔方密钥直接发JWT令牌。

不管哪一种登录方式,不管是MVC版还是API版魔方,最终目的都是给用户的这一次登录颁发一个访问令牌Token,同时把登录用户对象User保存一份到自定义Session。

注:自定义Session一定存在(MVC+API),它是综合了ASPNETCORE的Session/Cookie/Token等技术而创建的一个内存字典,分布式部署中多节点并不共用,优点是不存在序列化和网络开支。

验证

在魔方中获取当前已登录用户的方法是:ManageProvider.User

该静态属性内部会做很多事情,主要是从Session获取登录用户,若没有则找Token然后验证得到用户。感兴趣的同学可以看 ManagerProviderHelper.TryLogin ,里面的LoadToken/LoadUser是重点。

验证方案:

MVC版主流方案,登录后把User保存到自定义Session,使用时取出,缺点是不支持集群多节点部署;

API版主流方案,登录后颁发Token,写入Cookie,同时把User保存到自定义Session,使用时取出,集群多节点部署时,Session找不到值的节点,可以根据Token再次获取用户,无缝切换;

MVC版改进方案,参考API版,登录时也颁发Token,写入Cookie,在Session没有值的其它节点,也可以根据Token自动恢复用户。因为MVC版请求头没法带Token,因此只能借助Cookie;

MVC安全增强方案,某些安全审计机构认为,客户端在不带Token请求时,服务端不应该支持接口请求,参考,也就是要求禁止读写Cookie。魔方增加配置TokenCookie,对MVC版默认打开,对API版默认关闭。在关闭TokenCookie时,MVC版彻底依赖自定义Session保存已登录用户对象,此时不支持集群多节点部署。API版则不受影响,因为它除了Cookie传递Token,还可以通过Header/Query传递。

有的同学要问,如果关闭TokenCookie,也禁用ASPNETCORE的Session,魔方能够正常工作吗?

答案是肯定的!

关键就在于上面说的自定义Session之中。如果不允许在Cookie中写Token,也禁用了Session,那么魔方会创建一个随机字符串作为SessionId,结合内存缓存得到自定义Session这个内存字典。再把这个SessionId写入浏览器Cookie,名称是.Cube.Session

由于内存字典仅存在于单一进程,因为自定义Session不支持分布式多节点部署。在其它节点上,虽然根据这个SessionId也能创建出来自定义Session,但是里面是空的,跟其它节点的自定义Session不是同一个内存字典。

也许有同学要问,为何不能借助Redis,以SessionId为key,把Token保存到Redis里面呢?

这是可以的,但是太麻烦了。还不如注入NewLife.Redis作为Session实现,启用ASPNETCORE的Session啦。

对比

如果没有Session也没有TokenCookie,虽然能够通过自定义Session保持登录状态。但是默认20分钟就过去,然后跳回去登录页。用户体验不太好。

打开TokenCookie时,令牌在Cookie里面保存了一份,令牌有效期默认2小时。也就是说,至少2小时内不会跳转登录页,用户体验能够得到很大的改善。

总结

魔方登录总结(倒序):

1,从Session拿登录用户对象

2,密码登录/SSO登录/Token验证得到用户,填充Session

3,Token来源Header/Query/Cookie

4,API版没有Session,每次请求走32

5,MVC版默认从Cookie存Token,走321

6,MVC禁用TokenCookie后,走21

7,若ASPNET的Session被禁用,基于Cookie自己造一个Session,走21