关于多项目之间登录验证为什么需要共享session
服务器上部署了两个项目,登录之后才可以访问其中的接口。现在想要实现,当登录项目1成功后,可以不需要再登录项目2,直接可以访问项目2中的接口。
大部分人都会想到,共享session
,但是为什么是共享session
呢?
一、为什么需要共享session
以shiro
框架作为登录验证权限框架
为例,这里还不写这个,先说为什么需要共享session
,正常情况的时候,是如下图:
如上图描述,每个项目中shiro
都维护了自己的sessionid与session的关系
,它们之间不共享。
上图两个项目中切换请求必然会有如下的步骤:
1、sessionId串的生成
浏览器首次对项目1
发起请求时,项目1
会为当前请求创建一个session
,根据session
生成一个sessionId
字符串,该sessionId串
与创建的session
维护着一个关联关系。
2、sessionId串存到cookie中
后台将该sessionId串
返回给浏览器,浏览器将sessionId串
拿到后,存储到浏览器中的cookie
中。如下图:
3、再去请求项目2
当然,当前的这个sessionId串
仅仅对项目1
来说是认识的。如果这时候浏览器接着访问项目2
,(在http请求中,发起请求的一方总会把自身所带的所有cookie
打包到请求头中传给服务)。如下边两张图所示:
第一张为在去请求项目2
前,可以看到浏览器中的cookie
,此时共有三个,其中sessionId
对应的字符串是来自于项目1
登录成功后返回的 :
当我对项目2
发起请求,浏览器将现有的所有cookie
串统统放到了request headers
里,传了过去。
4、请求必然失败
这时候项目2
中已有的session
集合中无法根据当前传入进来的sessionId串
匹配成功的。因此登录不成功。
问题就看出来,是因为项目2
里的session
集合无法认识当前传入进来的sessionId
,匹配不到session
导致的访问失败。
二、共享session
后的逻辑
上边已大致说明为什么需要共享session
。那共享session
后,是什么逻辑,也备了一张图,下边的共享项目我已经共享到GitHub
中了。
先来说一下我的理解
,如下:
上图中master
项目为主项目,登录页即在这个项目中,suiteone
、suitetwo
为两个从项目,当两个从项目有请求时,如果没有登录的时候,都会打到master
项目的登录页上。共享session
采用的是redis
存储。
上图的步骤如下:
- 浏览器请求
master
项目,第一次请求的时候,也是会带着浏览器中的cookie
去请求,当然第一次去redis
里肯定找不到对应的session
,会通过⑤进入到登录页。 - 当在登录页输入完正确的账号密码后,才能登录成功,否则仍会回到⑤。
- 在这一步的时候,会将登录成功后的
session
,根据它,将生成sessionId串
,并传到前端浏览器中,浏览器以cookie
存储。 - 同时将第③步中生成的
session
存储到redis
中。 - 当前这里,不只是当登录失败的时候,会进入到登录页中,当浏览器长时间没有访问后台(每次浏览器访问后台,其实都会刷新
session
的过期时间expireTime
),导致session
超过时,也会进入到该步中。 - 当浏览器请求
suiteone
、suteTwo
这两个从项目时,肯定也是将当前浏览器中的所有的cookie
设置到request headers
请求头中。 - 根据传入的
sessionId串
到共享的redis
存储中匹配。 - 如果匹配不到,则会跳转到
master
项目的登录页,如果匹配成功,则会访问通过。
以上描述的并不难,大家也都会想到,那么如何将扯了这么多的淡
真正更简单的,落地实现才是大家关注的。
如果想了解具体shiro中如何实现的共享session
,可以参考下边的链接
[shiro框架—多项目登录访问共享session的实现]