抛开语言聊一聊SSO单点登录原理

一、背景

  每次有新同事加入到涉及单点登录系统的业务,都需要重复进行原理讲解和使用说明,效果还很一般,经常理解的一知半解,造成使用的不便以致影响业务进度;因此,重新梳理一下单点登录的逻辑,尽量文字化、图形化,用更简单的例子讲清楚。

二、目的

  让每个人都清楚单点登录的意义、实现原理和使用方法。

三、为什么使用单点登录?

  假设A公司专门负责销售服务器的,小王作为公司的销售人员,平时经常使用的就是公司的CRM系统和OA系统。今天,小王要通过CRM系统查一下客户B的信息,并且沟通出差事宜;然后呢,要通过OA系统提交一个出差事宜;整体的流程大致是这样的:

  小王 ->打开CRM -> 登录CRM -> 查看客户信息 -> 打开OA -> 登录OA -> 提交出差申请

  很明显,小王自己登录了两次,作为公司自己内部的两套系统,小王希望能够登录一次就可以访问CRM系统和OA系统,而这就是单点登录要实现的逻辑,多套系统使用一套用户体系,一次登录多个系统通行。

  小王 ->打开CRM -> 登录CRM -> 查看客户信息 -> 打开OA -> 提交出差申请

  然后,流程变成上面这样,用户操作更简单。当然,单点登录不仅仅是减少一次登录这么简单。

四、怎么实现单点登录

  上面我们讲了为什么使用单点登录,基于上面的流程,我们思考一下,关键点在于,打开OA时,我们怎么知道已经在CRM登录过了呢?

  我们先看一下使用CRM系统的正常的逻辑:

  打开CRM -> 浏览器检查登录cookie是否存在 -> 不存在进行登录 -> 登录成功,浏览器写入登录cookie -> 进入CRM

  再次打开CRM -> 浏览器检查登录cookie是否存在 -> 存在,并验证成功,直接进入CRM

  进入OA系统是同样的流程,但问题在于,基于cookie不能跨域访问的属性(这里不讨论二级域名的方式,有一定局限性),OA系统是不能访问到CRM系统的cookie的,所以,这就是我们单点系统需要解决的问题,也是整个系统的关键原理。

  关键原理就是实现一套单独的用户登录系统,作为所有系统的中介,对于用户的注册、登录、状态管理等统一管理,系统包括后台和前端两部分:

  SSO后台,实现用户注册、登录、状态检查等接口。

  SSO前端,实现统一的登录/注册页面,其他系统需要登录和注册时,全部跳转到该系统。

  好的,现在我们已经实现了单点登录,CRM系统和OA系统已经可以通过SSO中介共享登录状态了。好吧,不要骂人,现在我们一步一步还原整个业务流程:

  1. 首先打开CRM系统

  2. CRM系统会调用SSO后台的状态检查接口

  3. 这时候因为尚未登录过(其他系统都没有登录过),所以返回未登录

  4. CRM系统发现没有登录,跳转到SSO前端登录页面(这中间要传递参数过去,好让SSO前端登录成功后知道要跳回哪里)

  5. 小王输入自己的用户名和密码(当然,可能还有短信验证,这个和单点登录没有直接关系,不赘述)进行登录

  6. SSO前端调用SSO后台登录接口进行登录,登录成功跳转回CRM系统

  7. 这时已经登录进入CRM系统,可以查询客户信息等操作

  8. 小王拿到了CRM系统返回的客户信息,可以进行沟通或其他操作了

  9. 现在,打开OA系统

  10. OA系统会调用SSO后台状态检查接口

  11. 因为前面CRM系统已经登录,所以登录状态返回已登录

  12. 小王现在已经在OA系统里了,可以正常填写出差申请

  13. 在OA系统里提交申请后,可以等待领导审批了

  上面就是最终的单点登录流程,不过,我相信你还是一脸懵比,现在我们重复一下这个流程,并对关键点进行解释说明

  1. 首先打开CRM系统

  2. CRM系统会调用SSO后台的状态检查接口

    重点:状态检查接口是如何工作?

    状态检查接口要设置Access-Control-Allow-Credentials = true,意思是前端请求接口时会携带cookie内容

    前端调用ajax方式调用接口,要同时指定credentials = "include"

    状态检查接口会根据前端请求携带的cookie内容判断是否已登录,并检查登录的合法性和时效性等

    这个cookie内容何时写入的,请往下看

  3. 这时候因为尚未登录过(其他系统都没有登录过),所以返回未登录

  4. CRM系统发现没有登录,跳转到SSO前端登录页面(这中间要传递参数过去,好让SSO前端登录成功后知道要跳回哪里)

  5. 小王输入自己的用户名和密码(当然,可能还有短信验证,这个和单点登录没有直接关系,不赘述)进行登录

  6. SSO前端调用SSO后台登录接口进行登录,登录成功跳转回CRM系统

    重点:登录接口做了什么?

    登录成功后,登录接口以只读方式向浏览器写入了登录成功的cookie,cookie内容为登录用户的授权token

    这里写入的cookie就是上面第2步处使用的cookie

  7. 这时已经登录进入CRM系统,可以查询客户信息等操作

  8. 小王拿到了CRM系统返回的客户信息,可以进行沟通或其他操作了

  9. 现在,打开OA系统

  10. OA系统会调用SSO后台状态检查接口

    重点:这里会重复第2步的检查

    状态检查接口和登录接口都同属于SSO后台,在同一域名下,所以上面写入的cookie这里同样可以正常附加到状态接口的请求中

    状态检查接口通过检查token判断用户是否登录并在有效期,返回成功或失败。

  11. 因为前面CRM系统已经登录,所以登录状态返回已登录

  12. 小王现在已经在OA系统里了,可以正常填写出差申请

  13. 在OA系统里提交申请后,可以等待领导审批了

  

  至此,已经完成并实现了单点登录的主要业务功能,相信你也有了一个完整的理解,基本业务流程如下图:

  

 

  注意:

  1. SSO后台一旦设置Access-Control-Allow-Credentials = true后,Access-Control-Allow-Origin就不能再设置为 * 了。

  2. CRM系统和OA系统在调用状态检查接口成功后,可以将接口返回的token写在自己的cookie里,然后在调用自身业务系统的接口时,作为参数传递,这样就可以扩展出统一的权限管理。

  3. CRM系统和OA系统所有的页面,在一开始都要首先调用状态检查接口,根据返回结果,来判断跳转到SSO前端登录界面或进行正常操作(这里可以封装成一个统一方法)

 

  本文主要讲解SSO单点登录的思想和实现逻辑,无关乎语言,只要你真正理解了原理,相信你用任何语言都可以很快实现一套单点登录系统。

  如果错误,欢迎指正!

posted @ 2019-03-26 18:33  bcbr_wang  阅读(315)  评论(0编辑  收藏  举报