驽马十驾 驽马十驾

驽马十驾,功在不舍

目录
XXL-SSO单点登录核心设计个人总结
/  

XXL-SSO单点登录核心设计个人总结

参考项目:

整体流程

  • 应用1登录时,客户端拦截器判定到用户并未登录(或登录失效)的情况下,会将URL重定向到:sso-server-url/login?directUrl=client-web-url

  • 用户在服务端利用用户名密码等方式完成登录后,服务端大体会做3个事情:

    • 根据用户的id在持久化库(比如redis)中绑定当前id对应的具体用户信息,避免每次查询。
    • 根据上述的URL中的directUrl进行跳转,并在URL上带上sessionId,跳转URL:client-url?sessionId=123
    • 将这个sessinId保存在服务端自身的cookie中,用来保留当前已经登录的用户的状态
  • 用户端解析URL上的sessionId,判定读取是否已经登录成功,如果登录成功,那么将URL的非持久化的session转为cookie

  • 当应用2登录时,拦截器判定本地没有cookie,那么跳转到server,server检测到本地的cookie有上次登录的凭证,那么直接赋值给sessionId然后重定向回1

设计

分为2个部分,server部分和client部分。

server端

server部分的核心设计是:

  • 接收客户端传递过来的URL:?redirectUrl=xxx
  • 然后在login页面进行登录,登录完成后根据请求过来的URL上的redirectUrl进行回调,同时带上sessionId。
  • 同时将这个登录凭证保存到自己的cookie中
  • 其他客户端跳转到服务端的时候,检测到这个cookie,那么直接返回并退出

对外提供的接口部分有4个HTTP接口:

  • / 状态判定,如果没有登录,那么跳转到登录接口。如果已经登录,那么展示用户信息。
  • /login 客户端如果没有登录,那么会被拦截器重定向到该接口【后续解读】
  • /doLogin 登录接口
  • /loginout退出登录接口

client端

client部分的核心设计是拦截器,该拦截器做如下事情

  • 先从Cookie中获取用户的登陆key,如果存在那么从Redis中获取用户信息。
  • 当无法从Cookie中获取到登陆key时,会检测URL上是否有sessionKey,如果有那么会根据其获取用户信息,当获取到用户信息后会将SessionId转为Cookie。

简单而言,优先从cookie中获取,找不到采用sessinId获取。

整理

  • 因为不同的web对应的url不同,当出现跨域的时候,cookie是无法共享的,不过可以通过url进行明文共享
  • Client先从Cookie中获取,然后再考虑从SessinId中获取,该SessionId是Server重定向的时候,发送过来的

流程图

UserUserWeb1Web1SSO_ServerSSO_ServerWeb2Web2RedisRedis1登录2从Cookie中获取用户信息第一次肯定为空,继续3从URL中获取用户Key第一次肯定为空,继续4生成URL http://sso-server?directUrl=curUrl5URL发送给单点登录服务端6获取当前Cookie中是否有登录信息,若无7跳转到登录界面,进行登录,成功后8将用户Key和用户的信息写入Redis,缓存9将用户Key写入Cookie10根据带入的URL中的directUrl进行重定向,并在URL参数中带上用户Key11重定向到Web1,URL中带有用户Key12从Cookie中获取用户信息此次为空,继续13从URL中获取用户Key,成功获取14根据用户Key获取用户信息15将用户Key写入Cookie16登录成功17登录18从Cookie中获取用户信息第一次肯定为空,继续19从URL中获取用户Key第一次肯定为空,继续20生成URL http://sso-server?directUrl=curUrl21URL发送给单点登录服务端22获取当前Cookie中是否有登录信息因为之前已登录,所以存在23根据带入的URL中的directUrl进行重定向,并在URL参数中带上用户Key24重定向到Web2,URL中带有用户Key25从Cookie中获取用户信息此次为空,继续26从URL中获取用户Key,成功获取27根据用户Key获取用户信息28将用户Key写入Cookie29登录成功单点登录
骐骥一跃,不能十步。驽马十驾,功在不舍。