PHP单点登录

PHP 2016-08-10

你说你从我亲戚家来的,以为我会信吗。

起步

单点登录也不是什么新技术了,但是由于那次电话面试问了这个问题,我又有电话恐惧症,吞吞吐吐,没有回答好,觉得应该写下来以便以后回答能比较流畅容易理解。

单点登录SSO(Single Sign On)说得简单点就是在一个多系统共存的环境下,用户在一处登录后,就不用在其他系统中登录,也就是用户的一次登录能得到其他所有系统的信任。重点就在于让Session值在让不同服务器不同域名的情况下都可以访问。

要点

session共享技术的要点在于:

  • 所有的客户端的sessionid是同一个
  • 所有域名对应的服务器访问的Session的数据的位置必须一致

事先把hosts修改下,并将虚拟域名都指向同一个目录:

127.0.0.1       test1.open.dev
127.0.0.1       test2.open.dev
127.0.0.1       www.hong.dev

同服务器同域名(不同子域名)

这里的test1.open.dev和test2.open.dev我们认为是同一个域名,不同子域名。为此需要设置一下,设置有两种实现方式:

  • 在php最开始的地方,没有任何输出且在session_start()之前:

    ini_set('session.cookie_path', '/');
    ini_set('session.cookie_domain', '.open.dev');
    ini_set('session.cookie_lifetime', '1800');
    session_set_cookie_params(1800, '/', '.open.dev'); //这句可以替代前面三句,作用一致
  • php.ini里面设置,这个全局的,存在影响其他应用的隐患,不推荐。
    session.cookie_path = /;
    session.cookie_domain = .open.dev;
    session.cookie_lifetime = 1800;

    代码

    setting.php

    <?php
    ini_set('session.cookie_path', '/');
    ini_set('session.cookie_domain', '.open.dev');
    ini_set('session.cookie_lifetime', '1800');
    //session_set_cookie_params(1800, '/', '.open.dev');
    session_start();

test1.php

<?php
require 'setting.php';

$_SESSION['user'] = 'xiaoming';
print_r($_SESSION);

test2.php

<?php
require 'setting.php';

$_SESSION['sex'] = 'female';
print_r($_SESSION);

测试

浏览器依次访问: http://test1.open.dev/test/test1.php 输出:Array ( [user] => xiaoming ) http://test2.open.dev/test/test2.php 输出:Array ( [user] => xiaoming [sex] => female )

同服务器的不同域名

这里的难点就是cookie跨域去设置PHPSESSID的值。cookie共享的方式巧妙用的html的<stript>标签:在a域名下<script src="b.com/set_cookie.php"></script>

代码

set_cookie.php

<?php
setcookie('user', 'xiaohong', time() + 1800, '/');

get_cookie.php

<?php
print_r($_COOKIE);

b.php

<script src="http://test1.open.dev/test/set_cookie.php" />

访问:http://www.hong.dev/test/b.php //这个域名里设置其他域名的cookie 访问:http://test1.open.dev/test/get_cookie.php 输出:Array ( [user] => xiaohong ) 共享的cookie记得加密。

不同服务器同域名 和 不同服务器不同域名

通过中间者来实现,建立redies服务,然后是Redis数据共享,key就是session_id,值就是需要共享的数据。

这种解决方式可以解决包括前面的情况。


本文由 hongweipeng 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。

如果对您有用,您的支持将鼓励我继续创作!