做项目是web的,并且会有移动设备,以及未来会进行分布式部署,所以shiro作为权限管理的时候,就会出现session和应用分离的状况。
因为redis集成在了session中,所以session对shiro项目来说是透明的,这时,就需要前端能保存jsessionid来对项目进行请求的时候不需要再重新登录。
因为session存在redis,对我们是透明的,然后shiro关于sessionManager使用的是默认的配置,并没有对SessionDao进行重写。
然后就是前端携带jsessionId向后端请求了。
有两种方式,cookie和request header。
一般情况下,shiro在web端可以直接生成cookie,请求的时候,shiro默认获取cookie中的jsessionid,然后验证通过,调用业务接口。
在二般情况下呢,cookie被禁止。这时,request header就派上用场了。shiro会解析header的key/value值,所以这时间就可以让前端以cookie:JSESSIONID=XXXXXX的形式向应用请求。
下面是在postman中验证的过程(时间问题,不贴图了,只做过程描述):
postman中调用应用的登录接口,就会生成session,将jsessionid存储在cookies,这时header是没有cookie这个属性的。调用业务接口,可以成功。然后我们把浏览器的cookie禁止掉,这时,再调用业务接口,就获取不到jsessionid,也就无法获得session,然后我们把刚才cookie的值放在header中,再次调用业务接口,成功了。并且,测试过程中,把cookie打开,浏览器cookie设置jsessionid为id1,header的cookie设置为jsessionid=id2,此时调用接口获取session,返回的sessionid为id1,所以shiro是默认先获取浏览器的cookie的jsessionid,然后没有浏览器cookie的话,再去查找header的cookie参数的jsessionid的。
总结,登录成功后将sessionid返回给前端,让前端记录。登陆后前端每次请求接口时,默认设置header的cookie的值jsessionid。这样子第一,不用考虑浏览器是否禁用cookie,其次,满足除了web浏览器之外,移动设备(手持设备)、分布式部署、前后端分离的情况都可以满足。再者,session方面的配置使用shiro的默认设置即可。
PS,应用的HttpServletSession启动时候就集成redis这个是我们架构师做的,详细的原理我还没了解,暂时不提供解释。上面的方式就是针对目前这类项目(session存储redis但是对应用透明,项目前后端分离,使用shiro做权限管理)的设计做的对策。