php单点登录SSO(Single Sign On)的解决思路
一、什么是单点登录
解释:登录一个系统后,其它系统无需再次登录,即可进入。
二、举个例子:
你登录了淘宝,然后你进入天猫,发现你不用登录了。这时你要注意到,淘宝跟天猫可是完全不一样的域名。
你登录淘宝后,你的浏览器得到了cookie,但是这个cookie是在淘宝域名下的。你的天猫域名下并没有cookie。
这个时候你要想办法让天猫域名下也有这个相同的cookie。假设你的天猫域名下也有这个cookie。
当你的浏览器进入天猫时,你的浏览器会携带天猫域名下的cookie去服务器验证。
但是这个cookie对应的可是淘宝域名下的session数据,这个时候又该如何呢。
从这个例子中引出两个问题:
1、跨域种cookie
2、服务端保持cookie对应的session数据是一样的
三、解决思路
四、示例代码
A域名下的 index.php 文件
<?php
header("Content-type: text/html; charset=utf-8"); if(!empty($_POST)) {
$response = curl_post('http://www.U.com/index.php',$_POST);
if($response['code'] > 0) {
die('error:'.$response['msg']);
} set_cookie('SID',$response['data']['sid'],0,'/','',0,1);
echo '登录成功';
$url = 'http://www.B.com/setcookie.php?sid='.$response['data']['sid'];
die('<script type="text/javascript" src="'.$url.'" reload="1"></script>'); } function curl_post( $url , $arrPost = array() , $func = "http_build_query" ){
$ch = curl_init(); $opt[CURLOPT_URL] = $url;
$opt[CURLOPT_RETURNTRANSFER] = 1;
$opt[CURLOPT_TIMEOUT] = 10;
if( !empty( $arrPost ) ){
if( $func == 'json_encode' )
$opt[CURLOPT_HTTPHEADER] = array("Content-Type: application/json;charset=UTF-8");
$opt[CURLOPT_POST] = 1;
$opt[CURLOPT_POSTFIELDS] = call_user_func( $func , $arrPost );
} curl_setopt_array ( $ch, $opt );
$response = curl_exec( $ch );
curl_close( $ch ); return json_decode($response, true);
}
/**
* 免刷新写入cookie
* name 必需。规定 cookie 的名称。
* value 必需。规定 cookie 的值。
* expire 必需。规定 cookie 的有效期。
* path 可选。规定 cookie 的服务器路径。
* domain 可选。规定 cookie 的域名。
* secure 可选。规定是否通过安全的 HTTPS 连接来传输 cookie。
* httponly 可选。规定是否禁止js读取cookie。
*/
function set_cookie($name,$value='',$expire=0,$path='/',$domain='',$secure=0,$httponly=0) {
$_COOKIE[$name] = $value;
if(is_array($value)){
foreach($value as $k=>$v){
if(is_array($v)){
foreach($v as $a=>$b){
setcookie($name.'['.$k.']['.$a.']',$b,$expire,$path,$domain,$secure,$httponly);
}
}else{
setcookie($name.'['.$k.']',$v,$expire,$path,$domain,$secure,$httponly);
}
}
}else{
setcookie($name,$value,$expire,$path,$domain,$secure,$httponly);
}
}
?>
<!DOCTYPE HTML>
<html>
<head>
<title>A域名的登录框</title>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
</head>
<body>
<form action="http://www.A.com/index.php" method="post">
<input type="text" name="uname" placeholder="帐号"/>
<input type="password" name="upasswd" placeholder="密码"/>
<input type="submit" value="提交" />
</form>
</body>
</html>
B域名下的 index.php 文件
<?php
header("Content-type: text/html; charset=utf-8");
$sid = isset($_COOKIE['SID']) ? $_COOKIE['SID'] : ''; if(empty($sid)) echo "请先登录"; $response = curl_post('http://www.U.com/index.php',array('sid'=>$sid));
if($response['code'] > 0) {
die('error:'.$response['msg']);
} die('您的帐号密码是:'.$response['data']['uinfo']); function curl_post( $url , $arrPost = array() , $func = "http_build_query" ){
$ch = curl_init(); $opt[CURLOPT_URL] = $url;
$opt[CURLOPT_RETURNTRANSFER] = 1;
$opt[CURLOPT_TIMEOUT] = 10;
if( !empty( $arrPost ) ){
if( $func == 'json_encode' )
$opt[CURLOPT_HTTPHEADER] = array("Content-Type: application/json;charset=UTF-8");
$opt[CURLOPT_POST] = 1;
$opt[CURLOPT_POSTFIELDS] = call_user_func( $func , $arrPost );
} curl_setopt_array ( $ch, $opt );
$response = curl_exec( $ch );
curl_close( $ch ); return json_decode($response, true);
}
B域名下的 setcookie.php 文件
<?php
header("Content-type: text/html; charset=utf-8");
$sid = isset($_GET['sid']) ? $_GET['sid'] : ''; if(!empty($sid)) {
set_cookie('SID',$sid,0,'/','',0,1);
} /**
* 免刷新写入cookie
* name 必需。规定 cookie 的名称。
* value 必需。规定 cookie 的值。
* expire 必需。规定 cookie 的有效期。
* path 可选。规定 cookie 的服务器路径。
* domain 可选。规定 cookie 的域名。
* secure 可选。规定是否通过安全的 HTTPS 连接来传输 cookie。
* httponly 可选。规定是否禁止js读取cookie。
*/
function set_cookie($name,$value='',$expire=0,$path='/',$domain='',$secure=0,$httponly=0) {
$_COOKIE[$name] = $value;
if(is_array($value)){
foreach($value as $k=>$v){
if(is_array($v)){
foreach($v as $a=>$b){
setcookie($name.'['.$k.']['.$a.']',$b,$expire,$path,$domain,$secure,$httponly);
}
}else{
setcookie($name.'['.$k.']',$v,$expire,$path,$domain,$secure,$httponly);
}
}
}else{
setcookie($name,$value,$expire,$path,$domain,$secure,$httponly);
}
}
U域名下的 index.php 文件
<?php
header("Content-type: text/html; charset=utf-8"); $sid = isset($_POST['sid']) ? $_POST['sid'] : '';
if(!empty($sid)) {
$uname_upasswd = file_get_contents($sid);
if(empty($uname_upasswd)) {
die(json_encode(array(
'code'=>1,
'msg'=>'fail',
'data'=>array()
)));
}
die(json_encode(array(
'code'=>0,
'msg'=>'success',
'data'=>array('uinfo'=>$uname_upasswd)
)));
} $uname = isset($_POST['uname']) ? $_POST['uname'] : '';
$upasswd = isset($_POST['upasswd']) ? $_POST['upasswd'] : '';
if($uname == '' || $upasswd == '') {
die(json_encode(array(
'code'=>1,
'msg'=>'fail',
'data'=>array()
)));
} define('SID_SALT', '密码盐'); $passwd = passwd($uname.$upasswd,SID_SALT);
file_put_contents($passwd, $uname.','.$upasswd); die(json_encode(array(
'code'=>0,
'msg'=>'success',
'data'=>array('sid'=>$passwd)
))); function passwd($string,$salt) {
return md5(substr(md5($string).md5($salt),16,48));
}
验证流程:
1、进入A域名,输入帐号密码点击登录。
2、进入B域名,此时会打印出你在A域名输入的帐号密码。
注意:这只是一个简单的验证,实际开发中需要做cookie加密,实效验证等。而且,其实单点登录问题,还有其他解决思路。
php单点登录SSO(Single Sign On)的解决思路的更多相关文章
- java:sso(单点登录(single sign on),jsp文件动静态导入方式,session跨域)
1.jsp文件导入: 2.session跨域: 3.sso(单点登录(single sign on): sso Maven Webapp: LoginController.java: package ...
- 单点登录(Single Sign On)解决方案
单点登录(Single Sign On)解决方案 需求 多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统. A 网站和 B 网站是同一家公司的关联服务.现在要求,用户只要在其中一个网 ...
- 自己动手搭建 CAS(Central Authentication Service) 环境,为了单点登录(Single Sign On , 简称 SSO )
介绍 刚刚搭建 CAS 成功了,现在记录下来,怕以后忘记,同时也给需要帮助的人.CAS 搭建需要服务端和客户端,服务端是 Java 写的,如果自己搭建则需要安装与配置 Java 环境.客户端可以是多种 ...
- .NET基于Redis缓存实现单点登录SSO的解决方案[转]
一.基本概念 最近公司的多个业务系统要统一整合使用同一个登录,这就是我们耳熟能详的单点登录,现在就NET基于Redis缓存实现单点登录做一个简单的分享. 单点登录(Single Sign On),简称 ...
- 单点登录SSO
转载自 http://www.blogjava.net/xcp/archive/2010/04/13/318125.html 摘要:单点登录(SSO)的技术被越来越广泛地运用到各个领域的软件系统当 ...
- .NET基于Redis缓存实现单点登录SSO的解决方案
一.基本概念 最近公司的多个业务系统要统一整合使用同一个登录,这就是我们耳熟能详的单点登录,现在就NET基于Redis缓存实现单点登录做一个简单的分享. 单点登录(Single Sign On),简称 ...
- 十六、【适合中小企业的.Net轻量级开源框架】EnterpriseFrameWork框架核心类库之单点登录SSO
回<[开源]EnterpriseFrameWork框架系列文章索引> EFW框架源代码下载:http://pan.baidu.com/s/1qWJjo3U 单点登录(Single Sign ...
- Redis缓存实现单点登录SSO
.NET基于Redis缓存实现单点登录SSO的解决方案 .NET基于Redis缓存实现单点登录SSO的解决方案 一.基本概念 最近公司的多个业务系统要统一整合使用同一个登录,这就是我们耳熟能详的单 ...
- 《浅谈架构之路:单点登录 SSO》
前言:SSO 单点登录 “半吊子”的全栈工程师又来了,技术类的文章才发表了两篇,本来想先将主攻的几个系列都开个头(Nodejs.Java.前端.架构.全栈等等),无奈博客起步太晚,写博文的时间又没有很 ...
随机推荐
- bootstrap 模态
<script type="text/javascript" src="js/jquery-ui-custom.min.js"></scrip ...
- 8 search中的timeout参数
默认的search,是没有时间限制的.比如,一个search,可能要10分钟才能搜完,那么,es就会等10分钟,直到结果出来. 然而,在某些场景下,客户是等不了10分钟的.比如,电商网站,客户宁可 ...
- linux设备模型与内核中的面向对象思想
linux内核用C语言实现了C++面向对象的大部分特性:封装,继承,多态.在看内核的过程中,开始追寻其中的设计思想,封装.继承.多态.恰好今天又在看Linux设备模型,找了很多资料.总结如下: 1.l ...
- Python学习日记(二十四) 继承
继承 什么是继承?就是一个派生类(derived class)继承基类(base class)的字段和方法.一个类可以被多个类继承;在python中,一个类可以继承多个类. 父类可以称为基类和超类,而 ...
- Cephfs 部署 创建 metadata 池 data池
上一次部署了ceph分布式存储,接下来我们部署ceph的文件系统.Ceph文件系统至少需要两个RADOS池,一个用于数据,一个用于元数据. 创建metadata 池 后面数字表示 PG 和pgp数 c ...
- 基于335X的Linux网口驱动分析
基于335X的linux网口驱动分析 一. 系统构成 1. 硬件平台 AM335X 2. LINUX内核版本 4.4.12 二. 网口驱动构架(mdio部分) mdio网口驱动部分 使用 总线.设 ...
- 【DRF框架】认证组件
DRF框架的认证组件 核心代码: self.perform_authentication(request) 框架自带模块: from rest_framework import a ...
- [ipsec][strongswan] VirtualPN隧道网络加速FEC(forward error correction)
引用 跟一个网友就有关IPsec的网络加速以及降低延迟等问题进行了一些讨论,并总结了一写粗浅的看法. 因为FEC的资料并不多,所以分享出来,希望能被有需要的人看见:) 先说一下FEC. 我们使用ips ...
- css详解4
1.固定定位 固定定位,页面内容多,页面滚动起来,才能看到固定定位效果. 比如下面这个,随之滚动条滚动它一直在右边.比如固定导航栏,小广告,回到顶部,应用在这些地方.一直固定位置不变的. 首先让页面能 ...
- 搭建React项目环境【1】
1.安装NodeJS6.0以上自带npm依赖包管理工具 2.webstrom 2019.2 工具 1.在cmd输入node -v就可以看到node的当前版本 2.在输入node进入node环境 3.查 ...