web登录分析(简单登录与单点登录)

简单登录

登录流程

首先让我们分析一下一个简单的登录是怎么实现的。

  1. 一个简单的登录流程

    • 用户输入url访问站点,接受用户请求后判断用户是否已经登录,若未登录则跳转到登录页面
    • 用户访问登录页面,填写并提交登录表单
    • web应用对登录表单进行验证,若验证失败,则返回错误信息给用户;若验证成功,则将用户相关的信息(通常为用户id等信息)写入到当前的session中,将session id以cookie的形式发送给用户(同时可以将session中的身份信息以cookie的形式发送给用户,这个是可选的,使用该cookie可以实现自动登录,如下面的“登录分析图”中所示)。
    • 用户登录后,后续的访问中会将其获得的包含session id的cookie传递给web应用,若web应用能根据session id从session中获取到相应的身份信息(甚至进一步从数据库查找到相关的用户数据),则代表用户成功登录。
  2. 退出登录
    退出登录主要包括以下两个流程

    • 销毁session信息 (在服务端销毁)
    • 销毁客户端的相关cookie(包含session id的cookie)

自动登录

通常来说,服务器端的session会有一定的过期时间,同样的,客户端中包含session id的cookie也有过期时间。若用户登录后,长时间没有发出访问请求,则等到用户再次访问时,可能服务端的session或客户端的cookie已经失效,导致服务器判断用户为“未登录”,而实际上用户并没有退出登录过。可以通过实现“自动登录”来解决这个问题,即在session失效的时候,可以重新自动登录。

自动登录的基本思路:

  1. 在用户登录后,除了生成session id对应的cookie,还会生成一个包含用户身份信息的cookie(假设这个cookie的key为identity)。identity cookie包含的信息可以有:用户id,用户authKey(这个比较重要,authKey的功能有点类似于password),cookie持续时间等。为了达到自动登录的目的,通常会将该cookie的过期时间设置的特别长(可以是一个星期甚至一个月)。
  2. 在用户session失效后,用户再次访问web应用,会带上identity cookie(因为该cookie的有效期较长)。web应用首先判断用户为“未登录”状态(因为session失效了)。
  3. web应用尝试通过identity cookie为用户自动登录。应用从identity cookie中获取“用户id”和“用户authKey”,通过与数据库中的数据进行对比,校验“用户authKey”的有效性。
  4. 用户authKey认证有效后,web应用为用户生成新的session,并将新的session id放入cookie发送给用户。(即用户登录成功的标志为获取到包含session id的cookie)

例子分析(yii1.1与yii2)

  1. yii1.1原生登录分析
    yii1.1原生登录分析

    原文件和图片下载百度云盘链接

  2. yii2原生登录分析
    图片描述

    原文件和图片下载百度云盘链接

小结

  1. cookie,session是实现登录的核心
  2. 对应关系链: 客户端的cookie(包含了session id) ---> session id对应服务器端的session(包含了用户的身份信息,如id) ---> 根据session中的信息,可以进一步从数据库中获取用户的详细信息(甚至是其相应的权限)

单点登录介绍

什么是单点登录?

单点登录(Single sign-on,缩写为 SSO),又译为单一签入,一种对于许多相互关连,但是又是各自独立的软件系统,提供访问控制的属性。在拥有这项属性的环境中,当用户在某个系统登录时,就可以获取所有系统的访问权限,不用对每个单一系统都逐一登录。这项功能通常是以轻型目录访问协议(LDAP)来实现,在服务器上会将用户信息存储到LDAP数据库中。相同的,单一注销(single sign-off)就是指,只需要单一的注销动作,就可以结束对于多个系统的访问权限。(即,在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统;用户只需要退出登录一次就可以退出所有的应用系统

单点登录的优点

  • 降低访问第三方网站风险(用户密码不存储或外部管理)。
  • 用户不需要在不同的站点使用不同的用户名和密码,减少“密码疲劳”(password fatigue )。
  • 减少在使用不同站点时花费时间来重新输入密码进行身份验证。
  • 降低IT成本。

web单点登录的基本思路

  1. 当用户第一次访问应用系统1的时候,因为还没有登录,会被引导到认证系统中进行登录(1)
  2. 根据用户提供的登录信息, 认证系统进行身份校验,如果通过效校验,返回给用户一个认证的凭据ticket(2)
  3. 用户重新访问应用系统1,此时会带上ticket。应用系统1接受到请求后会把ticket发送到认证系统进行校验,检查ticket的合法性;若ticket合法性验证通过(代表用户已经登录),则用户可以访问应用系统1
  4. 用户再访问别的应用的时候(3,5)也会将这个ticket 带上,作为自己认证的凭据,应用系统接受到请求之后会把ticket送到认证系统进行效验,检查ticket的合法性(4,6)。如果通过效验,用户就可以在不用再次登录的情况下访问应用系统2和应用系统3了。
  • 单点登录机制

总结:ticket是整个系统的核心,ticket会在用户,应用系统,认证系统的交互中传输,最终达到实现单点登录的目的。ticket是所有系统对用户的统一的认证标志。

单点登录会遇到的问题

Q1:ticket是什么?由什么组成?
正如前面所说,ticket是所有系统对用户的统一的认证标志。在具体的实现中,我们可以用cookie来实现ticket的功能。最简单的,一个包含session id的cookie就可以看成是一个ticket。在后续对具体实现的分析中,我们会更深入地理解ticket。出于安全需要,通常我们会对ticket进行加密。要实现SSO的功能,让用户只登录一次,就必须让应用系统能够识别已经登录过的用户。应用系统应该能对ticket进行识别和提取,通过与认证系统的通讯,能自动判断当前用户是否登录过,从而完成单点登录的功能。

Q2:单点登录在技术实现上有哪些分类?
在技术实现上,单点登录可以分为跨子域单点登录完全跨域单点登录

Q3:什么是跨子域单点登录?其实现的具体思路是什么?
跨子域单点登录即在具有相同根域名的站点之间实现单点登录。例如,有以下站点a.example.com, b.example.com, p.example.com(认证中心),它们都有一个共同的根域名“example.com”。在单点登录写cookie时,把cookie的域设为它们共同的父域(即“example.com”),这样在不同的子域名下都可以使用同一个cookie(即ticket);与此同时,可以让多个系统共享session信息。

Q4:什么是完全跨域单点登录?其实现的具体思路是什么?
完全跨域单点登录即具有不同根域名的站点之间实现单点登录。实现思路:每个站点需要有自己的ticket(A-tikcet,B-ticket,P-ticket);当访问应用系统(A,B)时,若没有相应的ticket,则自动重定向到认证系统(P),在认证系统认证获得P-ticket后重定向到应用系统(A或B),用P-tikcet换取相应的A-ticket或B-ticket;注销的时候要注销所有的ticket(P-ticket,A-ticket,B-ticket)

Q5:Q3中共享cookie的方式存在什么局限?
首先,应用群域名得统一;其次,应用群各系统使用的技术(至少是web服务器)要相同,不然cookie的key值(tomcat为JSESSIONID,php为PHPSESSID)不同,无法维持会话,共享cookie的方式是无法实现跨语言技术平台登录的,比如java、php、.net系统之间;第三,cookie本身不安全。


单点登录实现

跨子域单点登录

跨子域单点登录的实现相对比较简单,可以基于cookie来实现,基本思想如下:

  1. 前提: 应用群中各个站点的域名需要统一,即具有相同的根域名;应用群使用的技术要相同,这样才能够维持回话(例如tomcat下cookie的key值为JSESSIONID,而PHP技术栈下则为PHPSESSID)
  2. 在前面所述的“web单点登录的基本思路”的基础上,将ticket具体实现为cookie中的session id,并且可以省略应用到认证中心对ticket进行校验的步骤。

具体图示如下:
单点登录时序图(跨子域单点登录)

1.当用户访问系统1(域名为a.example.com)时,系统检测到用户的请求中没有ticket(即没有相应的cookie),则判断用户未登录,将用户重定向到认证中心(带上系统1的url,则认证完后认证中心可将用户重定向会系统1)

2.用户提交登录表单到认证中心,验证通过后创建相应的session。将session id作为ticket,以cookie的方式发送给用户,并将用户重定向到系统1。(注意,cookie的域为根域“example.com”

3.用户重定向到系统1(此时会带上相应的cookie作为ticket)。系统1检测到有ticket,则向认证中心发起请求,验证ticket的有效性。

4.认证中心验证ticket的有效性(即确实有对应的session),将校验结果返回给系统1

5.系统1从认证中心得到校验成功的结果后,则可以认为用户“已登录”。

6.用户继续访问系统2(因为系统2的域名为“b.example.com”,其根域名也为“example.com”,故此时会带上相应的cookie作为ticket)。系统2检测到有ticket,则向认证中心发起请求,验证ticket的有效性。

7.认证中心验证ticket的有效性(即确实有对应的session),将校验结果返回给系统2。

8.系统2从认证中心得到校验成功的结果后,则可以认为用户“已登录”。

完全跨域单点登录

完全跨域单点登录的实现思路正如前面所述,这里复述一下:
1.每个站点需要有自己的ticket(假设:系统1为A-tikcet,系统2为B-ticket,认证中心为P-ticket)
2.当访问应用系统(系统1,系统2)时,若没有相应的ticket,则自动重定向到认证系统(P),在认证系统认证获得P-ticket后重定向到应用系统(系统1或系统2),用P-tikcet换取相应的A-ticket或B-ticket;注销的时候要注销所有的ticket(P-ticket,A-ticket,B-ticket)

具体图示如下:
注意: 在具体的实现中,可以用cookie来实现tikcet。ticket可以是包含session id的cookie。
单点登录时序图(完全跨域单点登录)

1.用户访问系统1,系统1发现用户未登录(没有A-ticket),跳转至认证中心,并带上系统的url作为参数(即回调url,这样认证后就可以跳转回来了)。

2.认证中心发现用户未登录(没有P-ticket),将用户引导至登录界面。

3.用户提交登录信息到认证中心。

4.认证中心校验用户的登录信息,通过验证后,创建一个全局session,生成一个绑定当前session的P-ticket。然后将P-ticket发送给用户,并将用户重定向到系统1(注意,此时会带上P-ticket)。

5.系统1接收到带有P-ticket的请求后,会向认证中心发出一个请求,验证P-ticket的有效性。

6.认证中心接收到系统1的校验请求,将校验结果返回给系统1。同时若验证通过则会将映射关系(P-ticket,系统1)记录到一个映射表中(称该表为“注册系统表”,即记录那些登录的子系统与P-ticket的对应关系,这样在用户注销的时候就可以向相应的子系统发送请求,销毁相应的局部session)。

7.系统1接受到认证中心的校验结果,若校验通过,则认为用户是“已登录”,系统1在自身系统为用户创建一个session(局部session),并生成一个绑定该session的A-ticket,同时将映射关系(A-ticket,P-ticket)记录到自己的一个映射表中(称该表为“ticket映射表”)。然后系统1将A-ticket发送给用户,在后续用户对系统1的访问中,会带上A-ticket,则可以通过A-ticket判断用户是否已经登录。

8.用户访问系统2,系统2发现用户为登录(没有B-ticket),跳转到认证中心(此时对认证中心的访问会带上P-ticket),并带上系统2的url作为参数(即回调url,这样认证后就可以跳转回来了)。

9.认证中心发现用户已经登录(因为用户已经持有P-ticket),确认P-ticket的有效性后即可认为用户“已登录”。认证中心将用户重定向到系统2(带上P-ticket)。

10.系统2接收到带有P-ticket的请求后,会向认证中心发出一个请求,验证P-ticket的有效性。

11.认证中心接收到系统2的校验请求,将校验结果返回给系统2。同时若验证通过则会将映射关系(P-ticket,系统2)添加到“注册系统表”

12.系统2接受到认证中心的校验结果,若校验通过,则认为用户是“已登录”,系统2在自身系统为用户创建一个session(局部session),并生成一个绑定该session的B-ticket,同时将映射关系(A-ticket,P-ticket)记录到自己的一个映射表中(称该表为“ticket映射表”)。然后系统2将B-ticket发送给用户,在后续用户对系统2的访问中,会带上B-ticket,则可以通过B-ticket判断用户是否已经登录。


注销图示:
注销(完全跨域单点登录)

1.用户向系统1发起注销请求(会带上A-ticket)。

2.系统1根据映射表“ticket映射表”,取出相应的P-ticket。系统1向认证中心发起注销请求(带上P-ticket)。

3.认证中心接收到注销请求后,验证P-ticket的有效性。若P-ticket有效,则销毁本地的全局session(根据P-ticket)。认证中心从“注册系统表”中查找出与P-ticket相关的所有系统,向所有相关的系统发送注销局部会话请求。

4.系统2接收到认证中心的“注销局部会话”请求,根据P-ticket从“ticket映射表”中取出相应的B-ticket,根据B-ticket销毁本地局部会话。

5.系统1接收到认证中心的“注销局部会话”请求,根据P-ticket从“ticket映射表”中取出相应的A-ticket,根据A-ticket销毁本地局部会话。


值得注意的地方:
1.在上面的实现中,我们可以看到P-ticket是需要在各个端传递的,故出于安全考虑,应该对P-ticket做一些安全性处理,如加密等。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值