1、第一版的逻辑,从SSO获取到用户信息之后放到session中,避免每次访问SSO获取用户信息,如下:
如上:每次请求从session中获取用户信息,从cookie中获取token信息,两者都有的情况下视为已登入,直接跳转到首页。如果只有token值没有用户信息,则用token访问SSO获取用户信息;如果token值为空,则用申请的clientId向SSO站点申请访问令牌,此时弹出的是登入页面,输入帐号与密码,提交后SSO将请求重定向到本服务的,并将令牌code传回,然后用code和clientId与client_secret去申请token,之后将token值存储在cookie中返回给浏览器,用户信息存储在session中。
问题:在测试环境和预发环境就一台机器,所以没有问题,但是线上是两台机器,导致在session中获取不到用户信息。
原因:1、如上图,获取到用户信息之后会用request.getSession(true).setAttribute("userinfo", userInfo);把用户信息放到session中。request.getSession是在服务器端运行的,意义相当于用request中保存的sessionid,去服务器的内存里找到对应的session,而不是从request中取出session对象。
2、线上若在A机器上把用户信息放在session中,即放在了A机器的内存中,而跳转到index@Controller时访问的是B机器,而B机器的内存session对象中并没有用户信息。
3、Cookies是域名级别的,session是机器级别的,改成不存用户信息,而是拿Cookies中的token值去授权中心拿用户的信息。如下: