先说一下这样做的好处吧,先来三个屌丝域名:

www.openpoor.com

myspace.openpoor.com

passport.openpoor.com

大家都知道,虽然他们都是一个域名但主机名不同,依然不能共享cookie(没有设置到域名.openpoor.com),这就导致用户在这些域名之间切换的时候需要重新登录,这是不能忍受的,所以需要同步登录;

先来讨论一下为什么要多个域名吧,我认为应该有一下几个好处;

  1. 功能明确;
  2. 主机名也等于一个参数,在当前restfull,短链接盛行的情况下,还是很有用的;
  3. 便于负载均衡,功能分配;

对于第三点在一些复杂业务逻辑下是非常有用的,当某些功能只能负载到一些特定的主机上时,例如静态文件,大量存储的图片,特别是及时生成的文件等等;

进入正题,能够同步登录,就需要让用户的浏览器记录每个域名的cookie,那么必须要让浏览器请求一次这些主机,方法很简单在页面中加入其他域名的链接如<script type="text/javascript" src="http://otherdomain"></script>一些浏览器默认不接受第三方的cookie写入,必须添加P3P HTTP header 来尝试(当然并不一定有效);

我简单做了一个demo,加密使用des;编辑/etc/hosts文件添加

127.0.0.1       passport.openpoor.com
127.0.0.1 www.openpoor.com
127.0.0.1 myspace.openpoor.com

passport.openpoor.com主要做的事情就是通知其实主机写入cookie;

首先是index.php

<?php session_start(); ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <title>sync login</title> </head> <body> <?php if(empty($_SESSION['username'])):?> hello,游客;请先<a href="login.php">登录</a> <?php else: ?> hello,<?php echo $_SESSION['username']; ?>;<a href="http://myspace.openpoor.com/synclogin/index.php">进入空间</a> <?php endif; ?> &nbsp; <a href="http://www.openpoor.com/synclogin/index.php">home</a> </body> </html>

然后是login.php

<?php session_start(); if(!empty($_POST['username'])){ require __DIR__.'/Des.php'; $_SESSION['username'] = $_POST['username']; $redirect = 'http://www.openpoor.com/synclogin/index.php'; header('Location:http://passport.openpoor.com/synclogin/sync.php?redirect='.urlencode($redirect).'&code='.Des::encrypt($_POST['username'],'openpoor'));exit; } ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <title>sync login</title> </head> <body> <form action="" method="post"> <input type="text" name="username" placeholder="用户名"/> <input type="text" name="password" placeholder="密码"/> <input type="submit" value="登录"/> </form> </body> </html>

这里没有做什么检查,用户登录成功之后,跳转http://passport.openpoor.com/synclogin/sync.php需要什么信息就可以自己添加,这里仅仅传递加密后的用户名(这里的加密是必须的,https就不说了);

在来看看sync.php做了什么

<?php $redirect = empty($_GET['redirect']) ? 'www.openpoor.com' : $_GET['redirect']; if(empty($_GET['code'])){ header('Loaction:http://'.urldecode($redirect)); exit; } $apps = array( 'myspace.openpoor.com/synclogin/slogin.php' ); ?> <!DOCTYPE html> <html> <head> <meta charset="UTF-8"/> <?php foreach($apps as $v): ?> <script type="text/javascript" src="http://<?php echo $v.'?code='.$_GET['code'] ?>"></script> <?php endforeach; ?> <title>passport</title> </head> <body> <script type="text/javascript"> window.onload=function(){ location.replace('<?php echo $redirect; ?>'); } </script> </body> </html>

passport.openpoor.com,请求所有的主机写入cookie,在页面加载完成之后跳转回去;

最后一个slogin.php是每个需要同步登录的域名都需要的用户写入cookie;

<?php session_start(); header('Content-Type:text/javascript; charset=utf-8'); if(!empty($_GET['code'])){ require __DIR__.'/Des.php'; $username = Des::decrypt($_GET['code'],'openpoor'); if(!empty($username)){ header('P3P: CP="CURa ADMa DEVa PSAo PSDo OUR BUS UNI PUR INT DEM STA PRE COM NAV OTC NOI DSP COR"'); $_SESSION['username'] = $username; } } echo "function _(){window.status='ok';}";//这里只是随便返回

这里分享的都是极简的功能代码,仅仅是描述实现;

最后也分享一下Des.php虽说现在Aes才是最安全的,这里只是简单说明一下;

<?php /** *@see Yii CSecurityManager; */ class Des{ public static function encrypt($data,$key){ $module=mcrypt_module_open('des','', MCRYPT_MODE_CBC,''); $key=substr(md5($key),0,mcrypt_enc_get_key_size($module)); srand(); $iv=mcrypt_create_iv(mcrypt_enc_get_iv_size($module), MCRYPT_RAND); mcrypt_generic_init($module,$key,$iv); $encrypted=$iv.mcrypt_generic($module,$data); mcrypt_generic_deinit($module); mcrypt_module_close($module); return md5($data).'_'.base64_encode($encrypted); } public static function decrypt($data,$key){ $_data = explode('_',$data,2); if(count($_data)<2){ return false; } $data = base64_decode($_data[1]); $module=mcrypt_module_open('des','', MCRYPT_MODE_CBC,''); $key=substr(md5($key),0,mcrypt_enc_get_key_size($module)); $ivSize=mcrypt_enc_get_iv_size($module); $iv=substr($data,0,$ivSize); mcrypt_generic_init($module,$key,$iv); $decrypted=mdecrypt_generic($module,substr($data,$ivSize,strlen($data))); mcrypt_generic_deinit($module); mcrypt_module_close($module); $decrypted = rtrim($decrypted,"\0"); if($_data[0]!=md5($decrypted)){ return false; } return $decrypted; } }

参考地址:https://my.oschina.net/empty125/blog/215942

php sso 单点登录的实现 代码示例的更多相关文章

  1. oauth2.0实现sso单点登录的方式和相关代码

    SSO介绍 什么是SSO 百科:SSO英文全称Single Sign On,单点登录.SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统.它包括可以将这次主要的登录映射到其他 ...

  2. cas sso单点登录系列4_cas-server登录页面自定义修改过程(jsp页面修改)

    转:http://blog.csdn.net/ae6623/article/details/8861065 SSO单点登录系列4:cas-server登录页面自定义修改过程,全新DIY. 目标:    ...

  3. SSO单点登录系列4:cas-server登录页面自定义修改过程(jsp页面修改)

    落雨 cas 单点登录 SSO单点登录系列4:cas-server登录页面自定义修改过程,全新DIY. 目标:    下面是正文: 打开cas的默认首页,映入眼帘的是满眼的中文and英文混杂体,作为一 ...

  4. 使用 JSONP 实现简单的 SSO 单点登录

    SSO 即 Single Sign On(单点登录).  一.二级域名之间的单点登录 不需要用到JSONP 或者 p3p 协议,直接使用 COOKIE 就行了,因为顶级域名相同就能实现 COOKIE ...

  5. [sso] 单点登录认证流程

    一.流程说明 第一步:访问cas过滤链接ssoLogin,拼凑定向到 CAS_SERVER 获取ticket的URL 第二步:CAS_SERVER校验用户信息,生成Ticket 第三步:重新定向到访问 ...

  6. .NET Core2.0+MVC 用Redis/Memory+cookie实现的sso单点登录

    之前发布过使用session+cookie实现的单点登录,博主个人用的很不舒服,为什么呢,博主自己测试的时候,通过修改host的方法,在本机发布了三个站点,但是,经过测试,发现,三个站点使用的sess ...

  7. Docker 创建 Crucible4.6.1 以及与 Crowd3.3.2 实现 SSO 单点登录

    目录 目录 1.介绍 1.1.什么是 Crucible? 2.Crucible 的官网在哪里? 3.如何下载安装? 4.对 Crucible 进行配置 4.1.破解 Crucible 第一步 4.2. ...

  8. SpringCloud系列——SSO 单点登录

    前言 作为分布式项目,单点登录是必不可少的,文本基于之前的的博客(猛戳:SpringCloud系列——Zuul 动态路由,SpringBoot系列——Redis)记录Zuul配合Redis实现一个简单 ...

  9. [精华][推荐]CAS SSO单点登录服务端客户端学习

    1.通过下载稳定版本的方式下载cas的相关源码包,如下: 直接选择4.2.1的稳定代码即可 2.我们项目中的版本版本使用maven apereo远程库去下载 通过远程maven库下载cas-serve ...

随机推荐

  1. [POJ] 1562 Oil Deposits (DFS)

    Oil Deposits Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 16655   Accepted: 8917 Des ...

  2. UI弹出键盘和收回键盘

    点击textfield,会自动弹出键盘 要让键盘收回来,先设置个代理:[field setTextFieldDelegate:self];  可设置成自己,也可设置成其他对象,只要在对应的类中,遵循U ...

  3. Program Files 与Program Files (x86)

    在64位系统下,为了更好的兼容32位程序,在安装一些32位程序(注意某些程序他就是32位的),会默认扔到program files(x86)这个文件夹下,而一些64位的程序,或程序本身没有位数区别的, ...

  4. 把ResultSet对象转变成List对象

    private static List<Map<String, Object>> convertRS2List(ResultSet rs) throws SQLExceptio ...

  5. HDU 4585 Shaolin (set的应用)

    set是STL中非常方便的工具,可以实现自动去重和排序,可我一直忽视它的重要性,导致吃了好几次亏. 在思考这道题的时候,我一直往二分上靠拢,可是二分需要直接插入排序,直接插入排序覆盖的时候复杂度最大是 ...

  6. android基础知识点复习之短信发送

    界面布局: activity_main.xml <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/an ...

  7. 使用OpenCV查找二值图中最大连通区域

    http://blog.csdn.net/shaoxiaohu1/article/details/40272875 使用OpenCV查找二值图中最大连通区域 标签: OpenCVfindCoutour ...

  8. nefu 753 n!末尾有多少个0

    Problem : 753 Time Limit : 1000ms Memory Limit : 65536K description 计算N!末尾有多少个0 input 输入数据有多组,每组1行,每 ...

  9. Sharepoint 弹出消息提示框 .

    在event receiver中如何弹出一个类似winform中messagebox.show 的框? 那我要对用户显示一些错误信息或者提示信息怎么搞? 1. 如果是在ItemAdding或者其他进行 ...

  10. CentOS + EPEL YUM源地址

    [bizosv] name=bizsov-centos-$releasever - centos baseurl=http://yikat:yikat@download.bizsov.com/ gpg ...