zoukankan      html  css  js  c++  java
  • SSO 单点登录总结(PHP)

    本篇文章根据个人理解的知识整理汇总,如有不足之处,请大家多多指正。

    单点登录(SSO——Single Sign On)的应用是很普遍的,尤其在大型网站系统中,比如百度,登录百度账号和,再转到百度经验、百度贴吧等是不用重新登录的。本文将从 cookie 和 session 基础详细介绍单点登录的原理,代码实现为 PHP。

    Cookie 是由客户端访问服务器时服务器发送给客户端的特殊信息,且这些信息以文本文件的方式存储在客户端。第一次访问服务器时,服务器会在 HTTP 响应头(Response Header)返回 Cookie 信息。客户端保存 Cookie 信息之后,下次访问服务器时,HTTP请求头(Request Header)会包含 Cookie 信息。

    简单的说: 服务器不认识访问它的客户端,为了识别它们,就给每个访问它的客户端一个口令,服务器通过口令识别这些客户端。

    注意: 不是访问每个服务器都会返回 Cookie 的,只有服务器中有设置 Cookie ,才会返回给客户端。

    • 在本地服务器下的 test.php 中设置 Cookie
    <?php
    // Cookie 是 HTTP 标头的一部分,因此 setcookie() 函数必须在其它信息被输出到浏览器前调用,这和对 header() 函数的限制类似
    setcookie('testCookie', 'this is test cookie');
    
    • 通过浏览器访问本地服务器 localhost/test.php,报文如下:

    • 删除本地服务器下 test.php 中的 setcookie,再次访问 localhost/test.php,报文如下:

    简单登录示例:

    <?php
    # 登录
    setcookie('userName', 'test');
    
    # 判断是否已登录
    if (isset($_COOKIE['userName'])) {
        echo '已登录';
    }
    

    关于 Cookie 的具体用法暂时不多说明,本篇文章主要讲解机制原理

    Session

    Session 是服务器端使用的一种记录客户端状态的机制,使用上比Cookie简单一些,相应的也增加了服务器的存储压力。在客户端访问服务器时,服务器会创建 Session 并生成一个 Session id 发到客户端,客户端下次访问时需要带着 Session id,服务器则根据 Session id 找到相应的 Session。

    Session 生成和传递流程

    • 服务器设置 Session:localhost/session.php
    <?php
    session_start();
    $_SESSION['testSession'] = 'This is test';
    
    • 客户端浏览器访问服务器:localhost/session.php,报文如下图:

    • 客户端浏览器再此访问服务器(注释代码):localhost/session.php,报文如下:

    单点登录

    在介绍单点登录的方式之前先介绍一下 PHP 中的 Cookie 中的设置,方便容易理解

    bool setcookie ( string $name [, string $value = "" [, int $expire = 0 [, string $path = "" [, string $domain = "" [, bool $secure = false [, bool $httponly = false ]]]]]] )
    

    参数:

    • name: Cookie 名称。
    • value: Cookie 值。
    • expire: Cookie 的过期时间。
    • path: Cookie 有效的服务器路径。 设置成 '/' 时,Cookie 对整个域名 domain 有效。 如果设置成 '/foo/', Cookie 仅仅对 domain 中 /foo/ 目录及其子目录有效(比如 /foo/bar/)。 默认值是设置 Cookie 时的当前目录。
    • domain: Cookie 的有效域名/子域名。 设置成子域名(例如 'www.example.com'),会使 Cookie 对这个子域名和它的三级域名有效(例如 w2.www.example.com)。 要让 Cookie 对整个域名有效(包括它的全部子域名),只要设置成域名就可以了(这个例子里是 'example.com')。

    由上节我们知道,Session 是存放在服务器中的,客户端与服务器的通信会话是通过 Session id 识别的, 客户端 Session id 是存放在 cookie 中,因此单点登录大致分为:同域名不同站点登录、同域不同子域登录、不同域名登录。

    同域名不同站点登录

    由 PHP 中的 Cookie 设置说明可以看出,默认下不同站点是共享 Cookie 的除非设置了不同的有效服务器路径。如果设置了不同的有效的服务器路径怎么实现共享登录呢?哈哈哈,那就将有效服务器路径设置为默认 '/' 的就好了。

    同域不同子域登录

    同样,由 PHP 中的 Cookie 设置说明可以看出,只要设置 Cookie 的 domain(Cookie 的有效域名/子域名) 参数就可以了,如下:

    由于 PHP 中生成 Session 会自动配置 Cookie,因此我们可以直接在 Session 中设置 Cookie 有效域

    one.sso.test/create_session

    <?php
    session_set_cookie_params(time()+3600, '/', 'sso.test');
    session_start();
    $_SESSION['test'] = 'This is test';
    

    two.sso.test/get_session

    <?php
    session_set_cookie_params(time()+3600, '/', 'sso.test');
    session_start();
    echo $_SESSION['test'];
    

    其中后者是可以获取到 Session 值的。下边两图分别问以上两个子域名的报文和 Cookie 信息
    图一:

    图二:

    由图可见他们的 Session id 是相同的,因此调用的是服务器上的同一个 Session。

    注意:在 PHP 中,配置 Session 的 Cookie 信息,还可以通过修改 php.ini 文件设置

    session.cookie_path = /
    session.cookie_domain = '.sso.test'
    session.cookie_lifetime = 0
    

    不同域名登录

    由于涉及到用户信息安全问题,因此本文通过流程图大致说一下基本liu流程,具体操作看实际应用

    注意: 上图中的“返回 Cookie 信息”并不是单独返回的,而是在“跳转页面”的 HTTP 响应头(Response Header)返回,同样异步请求的也是在 JS 调用 www.sso2.com 时在 HTTP 响应头Response Header 返回。

    本文到此结束,后续如果有新的理解会补充上去。

  • 相关阅读:
    iOS 进阶 第一天(0323)
    iOS 基础 第五天(0811)
    iOS 基础 第四天(0809)
    iOS 基础 第三天(0808)
    iOS 基础 第三天(0807)
    iOS 基础 第二天(0805)
    iOS 基础 第一天(0804)
    Mac 启用http-dav功能(WebDAV服务器)
    【转】phpmyadmin万能密码漏洞
    关于python文件操作 (转载)
  • 原文地址:https://www.cnblogs.com/it-abel/p/9612143.html
Copyright © 2011-2022 走看看