1.访问资源接口:前端判断是否带token。
2.没有token,调用CRM代理的授权接口并带上系统标识(区分客户端用)
3.CRM代理的授权接口进行转发到uaa前端的授权页
4.uaa前端授权页调用uaa的代理授权接口。
5.uaa后端验证未登录,重定向到uaa登录页并带上系统标识。
6.输入账号和密码。
7.调用登录接口。
8.登录成功以后,由前端调用uaa的代理授权接口并带上系统标识。
9.授权成功后跳转到crm的授权码页面。
10.前端在授权码页拿到code,调用crm的代理获取token接口(crm系统的代理获取token接口直接调uaa的token接口)。
11.返回token,crm前端拿token访问资源。
已登录系统2.png
1.访问资源接口:前端判断是否带token。
2.没有token,调用CRM代理的授权接口并带上系统标识(区分客户端用)。
3.CRM代理的授权接口进行转发到uaa前端的授权页。
4.uaa前端授权页调用uaa的代理授权接口。
5.uaa后端验证已登录,跳转到cms的授权码页面。
6.前端在授权码页拿到code,调用crm的代理获取token接口(crm系统的代理获取token接口直接调uaa的token接口)
7.返回token,crm前端拿token访问资源。
刷新token.png
filter组成.png
从调用上来看,针对不同的请求,security-
oauth2对应的filter是不一样的。代码入口FilterChainProxy.doFilterInternal.
获取token、token_key等接口时会把Client_id和Client_secret做为身份信息去调用,其他的接口则必须走用户校验,所以两者是有区别的。
所以需要保证,授权的时候,session必须一致,这样才能拿到登录了的身份信息,所以流程里面只要是授权都要调到uaa前端统一去调用,以保证uaa后端能够根据sessionId拿到已登录的身份信息。
到此为止,统一登录的问题已解决。
接下来是解决统一登出的问题:
我采用的方案是:
1.登录成功后,将login:user_id作为key,时间戳作为值放入缓存中,在获取token的时候,从缓存中拿到值,放到jwt中。
2.资源服务器在解析token的时候,拿到token的附加信息loginVersion,然后将loginVersion与缓存中的值比较,不一致说明,已退出登录。
3.推出登录时将缓存的信息移除
demo地址(前后分离,包含前端代码):[https://github.com/mushang8923/sso-
jwt.git](https://links.jianshu.com/go?to=https%3A%2F%2Fgithub.com%2Fmushang8923%2Fsso-
jwt.git)