PHP编程 SSO详细介绍及简单实例


Posted in PHP onJanuary 13, 2017

PHP SSO详解

SSO有三种模式:①跨子域单点登陆②完全跨单点域登陆③站群共享身份认证

第一种模式很简单,只需要将Cookie的域设置成多个应用的根域即可

第二种方式,也很简单,就是将所以应用的认证地址更换成同一个认证地址,每次查看是否在认证中心登陆,如果登陆了,给调用应用发放一个加密令牌即可

第三种跨域,就是来回跳转来回验证token略有麻烦

配置目录结构

在服务器根目录下,新建三个项目目录:

|?/网站根目录/
|?|?/oa/
|?|?/bbs/
|?|?/blog/

在根目录下新建functions.PHP脚本文件,具体内容如下:

<?php

/**
 * 获取登陆token
 * @param string $url 获取token的地址
 * 2017-01-03T13:08:43+0800
 */
function getToken($url)
{
  $bool = isLogin();
  if ($bool) {
    // 如果登陆了跳转到本站首页
    header('location: index.php');
    exit();
  }

  // 否则没有登陆,去另一个站点看是否登陆
  header('location: '.$url);
}

// 校验令牌是否正确
function yzToken($domain)
{
  $url = isset($_GET['url']) ? $_GET['url'] : '';
  $username = isset($_GET['username']) ? $_GET['username'] : '';
  $token = isset($_GET['token']) ? $_GET['token'] : '';


  if (!empty($username) && !empty($token)) {
    $salt = 'taoip';
    $_token = md5($salt.$username);
    // 校验第三方站点过来时的token是否正确
    if ($_token == $token) {
      // 设置跳转过来的网站的Cookie
      setCook($username, $_token, $domain);
      header('location: index.php');
    }
  }

}

// 设置cookie
function setCook($username, $_password, $domain)
{
  // 校验成功,开始登陆
  setcookie('username', $username, time()+3600, '/', $domain);
  setcookie('token', $_password, time()+3600, '/', $domain);
  header('location: index.php');
}

// 判断是否登陆
function isLogin()
{
  $username = isset($_COOKIE['username']) ? $_COOKIE['username'] : '';
  $token = isset($_COOKIE['token']) ? $_COOKIE['token'] : '';
  $salt = 'taoip';

  $_token = md5($salt.$username);

  if ($token == $_token) {
    return true;
  } else {
    return false;
  }
}

?>

在oa项目目录下,新建index.php和login.php两个脚本文件

编辑index.php文件

<?php

// OA站点

// (1)开启Session会话
session_name('taoip');
session_start();
// (2)获取用户名和token进行校验
$username = isset($_COOKIE['username']) ? $_COOKIE['username'] : '';
$token = isset($_COOKIE['token']) ? $_COOKIE['token'] : '';

$salt = 'taoip';

$_token = md5($salt.$username);

if ($token != $_token) {
  header('location: login.php');
  exit();
}

echo "欢迎{$username}用户,访问OA站点";

?>

编辑login.php文件

<?php

// OA站点登陆系统
require '../functions.php';

// (2)验证
yzToken('taoip.cn');

// (1)判断是否登陆,登陆则跳转首页,未登录则去其他站点获取token
$url = isset($_GET['url']) ? $_GET['url'] : '';
if (empty($url)) {
  getToken('http://dengpeng.cc/login.php?url=http://oa.taoip.cn/login.php');
}

// (1)判断用户是否登陆
$bool = isLogin();
$url = isset($_GET['url']) ? $_GET['url'] : '';
if ($bool) {
  if (empty($url)) {
    header('location: index.php');
  } else {
    $username = isset($_COOKIE['username']) ? $_COOKIE['username'] : '';
    $token = isset($_COOKIE['token']) ? $_COOKIE['token'] : '';
    $lurl = $url.'?username='.$username.'&token='.$token;
    header('location: '.$lurl);
  }
}


if (!empty($_POST)) {
  $username = isset($_POST['username']) ? $_POST['username'] : '';
  $password = isset($_POST['password']) ? $_POST['password'] : '';

  // 从库中查询用户密码
  @$link = mysql_connect('localhost', 'root', '');
  mysql_query('use sso', $link);
  mysql_query('set names utf8', $link);
  $sql = "select * from users where username = '".$username."'";
  $user = mysql_fetch_assoc(mysql_query($sql, $link));

  // 校验
  $salt = 'taoip';
  $_password = md5($salt.$username);

  // var_dump($user['password'] == $_password);
  // print_r($user);exit();

  if ($user['password'] == $_password) {
    // 校验成功,开始登陆
    setcookie('username', $username, time()+3600, '/', 'taoip.cn');
    setcookie('token', $_password, time()+3600, '/', 'taoip.cn');
    // 如果URL没有值重定向到首页,否则重定向到URL页面
    if (empty($url)) {
      header('location: index.php');
    } else {
      header('location: '.$lurl);
    }
  }
}

?>

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="generator" content="Sublime Text 3114">
  <meta name="author" content="3@dengpeng.cc">
  <meta name="keywords" content="">
  <meta name="description" content="">
  <title>OA站点登陆系统</title>
</head>
<body>
  <div class="container">
    <h2>oa.taoip.cn站点登陆系统</h2>
    <form action="" method="post">
      <label for="">用户名</label>
      <input type="text" name="username">
      <br>
      <label for="">密码</label>
      <input type="text" name="password">
      <hr>
      <button type="submit">提交</button>
    </form>
  </div>
</body>
</html>

在bbs项目目录下,新建index.php和login.php两个脚本文件

编辑index.php文件

<?php
/**
 * @author DengPeng <3@dengpeng.cc>
 * @since 2017/01/03
 * @copyright copyright (c) 2017 zixue.it GPL
 * @license http://www.zixue.it/
 */

// BBS站点

// (1)开启Session会话
session_name('taoip');
session_start();
// (2)获取用户名和token进行校验
$username = isset($_COOKIE['username']) ? $_COOKIE['username'] : '';
$token = isset($_COOKIE['token']) ? $_COOKIE['token'] : '';

$salt = 'taoip';

$_token = md5($salt.$username);

if ($token != $_token) {
  header('location: login.php');
  exit();
}

echo "欢迎{$username}用户,访问BBS站点";

?>

编辑login.php文件

<?php
/**
 * @author DengPeng <3@dengpeng.cc>
 * @since 2017/01/03
 * @copyright copyright (c) 2017 zixue.it GPL
 * @license http://www.zixue.it/
 */

// BBS站点登陆系统
require '../functions.php';

// (2)验证
yzToken('taoip.cn');

// (1)判断是否登陆,登陆则跳转首页,未登录则去其他站点获取token
$url = isset($_GET['url']) ? $_GET['url'] : '';
if (empty($url)) {
  getToken('http://dengpeng.cc/login.php?url=http://bbs.taoip.cn/login.php');
}

// (1)判断用户是否登陆
$bool = isLogin();
$url = isset($_GET['url']) ? $_GET['url'] : '';
if ($bool) {
  if (empty($url)) {
    header('location: index.php');
  } else {
    $username = isset($_COOKIE['username']) ? $_COOKIE['username'] : '';
    $token = isset($_COOKIE['token']) ? $_COOKIE['token'] : '';
    $lurl = $url.'?username='.$username.'&token='.$token;
    header('location: '.$lurl);
  }
}


if (!empty($_POST)) {
  $username = isset($_POST['username']) ? $_POST['username'] : '';
  $password = isset($_POST['password']) ? $_POST['password'] : '';

  // 从库中查询用户密码
  @$link = mysql_connect('localhost', 'root', '');
  mysql_query('use sso', $link);
  mysql_query('set names utf8', $link);
  $sql = "select * from users where username = '".$username."'";
  $user = mysql_fetch_assoc(mysql_query($sql, $link));

  // 校验
  $salt = 'taoip';
  $_password = md5($salt.$username);

  // var_dump($user['password'] == $_password);
  // print_r($user);exit();

  if ($user['password'] == $_password) {
    // 校验成功,开始登陆
    setcookie('username', $username, time()+3600, '/', 'taoip.cn');
    setcookie('token', $_password, time()+3600, '/', 'taoip.cn');
    // 如果URL没有值重定向到首页,否则重定向到URL页面
    if (empty($url)) {
      header('location: index.php');
    } else {
      header('location: '.$lurl);
    }
  }
}

?>

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="generator" content="Sublime Text 3114">
  <meta name="author" content="3@dengpeng.cc">
  <meta name="keywords" content="">
  <meta name="description" content="">
  <title>BBS站点登陆系统</title>
</head>
<body>
  <div class="container">
    <h2>bbs.taoip.cn站点登陆系统</h2>
    <form action="" method="post">
      <label for="">用户名</label>
      <input type="text" name="username">
      <br>
      <label for="">密码</label>
      <input type="text" name="password">
      <hr>
      <button type="submit">提交</button>
    </form>
  </div>
</body>
</html>

在blog项目目录下,新建index.php和login.php两个脚本文件

编辑index.php文件

<?php
/**
 * @author DengPeng <3@dengpeng.cc>
 * @since 2017/01/03
 * @copyright copyright (c) 2017 zixue.it GPL
 * @license http://www.zixue.it/
 */

// blog站点

// (1)开启Session会话
session_name('taoip');
session_start();
// (2)获取用户名和token进行校验
$username = isset($_COOKIE['username']) ? $_COOKIE['username'] : '';
$token = isset($_COOKIE['token']) ? $_COOKIE['token'] : '';

$salt = 'taoip';

$_token = md5($salt.$username);

if ($token != $_token) {
  header('location: login.php');
  exit();
}

echo "欢迎{$username}用户,访问blog站点";

?>

<?php
/**
 * @author DengPeng <3@dengpeng.cc>
 * @since 2017/01/03
 * @copyright copyright (c) 2017 zixue.it GPL
 * @license http://www.zixue.it/
 */

// blog站点

// (1)开启Session会话
session_name('taoip');
session_start();
// (2)获取用户名和token进行校验
$username = isset($_COOKIE['username']) ? $_COOKIE['username'] : '';
$token = isset($_COOKIE['token']) ? $_COOKIE['token'] : '';

$salt = 'taoip';

$_token = md5($salt.$username);

if ($token != $_token) {
  header('location: login.php');
  exit();
}

echo "欢迎{$username}用户,访问blog站点";

?>

编辑login.php文件

<?php
/**
 * @author DengPeng <3@dengpeng.cc>
 * @since 2017/01/03
 * @copyright copyright (c) 2017 zixue.it GPL
 * @license http://www.zixue.it/
 */

// blog站点登陆系统
require '../functions.php';

// (2)验证
yzToken('dengpeng.cc');

// (1)判断是否登陆,登陆则跳转首页,未登录则去其他站点获取token
$url = isset($_GET['url']) ? $_GET['url'] : '';
if (empty($url)) {
  getToken('http://oa.taoip.cn/login.php?url=http://dengpeng.cc/login.php');
}


// (1)判断用户是否登陆
$bool = isLogin();
$url = isset($_GET['url']) ? $_GET['url'] : '';
if ($bool) {
  if (empty($url)) {
    header('location: index.php');
  } else {
    $username = isset($_COOKIE['username']) ? $_COOKIE['username'] : '';
    $token = isset($_COOKIE['token']) ? $_COOKIE['token'] : '';
    $lurl = $url.'?username='.$username.'&token='.$token;
    header('location: '.$lurl);
  }
}


// (3)判断用户是否提交数据
if (!empty($_POST)) {
  $username = isset($_POST['username']) ? $_POST['username'] : '';
  $password = isset($_POST['password']) ? $_POST['password'] : '';

  // 从库中查询用户密码
  @$link = mysql_connect('localhost', 'root', '');
  mysql_query('use sso', $link);
  mysql_query('set names utf8', $link);
  $sql = "select * from users where username = '".$username."'";
  $user = mysql_fetch_assoc(mysql_query($sql, $link));

  // 校验
  $salt = 'taoip';
  $_password = md5($salt.$username);

  // var_dump($user['password'] == $_password);
  // print_r($user);exit();

  if ($user['password'] == $_password) {
    setCook($username, $_password, 'dengpeng.cc');
    if (empty($url)) {
      header('location: index.php');
    } else {
      header('location: '.$lurl);
    }
  }
}

?>

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="generator" content="Sublime Text 3114">
  <meta name="author" content="3@dengpeng.cc">
  <meta name="keywords" content="">
  <meta name="description" content="">
  <title>blog站点登陆系统</title>
</head>
<body>
  <div class="container">
    <h2>dengpeng.cc站点登陆系统</h2>
    <form action="" method="post">
      <label for="">用户名</label>
      <input type="text" name="username">
      <br>
      <label for="">密码</label>
      <input type="text" name="password">
      <hr>
      <button type="submit">提交</button>
    </form>
  </div>
</body>
</html>

配置本地虚拟主机

具体配置步骤,我想大家应该都会了,不需要我一一赘述.你只需要按照我给的参照,配置和不同域名对应目录的映射即可.

域名 /项目目录/
oa.taoip.cn /oa/
bbs.taoip.cn /bbs/
dengpeng.cc /blog/

恭喜您,已经完成了一个简单的SSO系统

配置完成后,记得重启Web服务器.然后你只需要访问这三个不同的站点,即可实现一个站点登陆,其他站点不再发送登陆请求.

感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!

PHP 相关文章推荐
在数据量大(超过10万)的情况下
Jan 15 PHP
网页游戏开发入门教程三(简单程序应用)
Nov 02 PHP
PHP冒泡排序算法代码详细解读
Jul 17 PHP
Ajax实时验证用户名/邮箱等是否已经存在的代码打包
Dec 01 PHP
PHP超级全局变量数组小结
Oct 04 PHP
PHP在不同页面间传递Json数据示例代码
Jun 08 PHP
全面解析PHP操作Memcache基本函数
Jul 14 PHP
PHP实现链式操作的原理详解
Sep 16 PHP
php实现微信扫码支付
Mar 26 PHP
php cli模式下获取参数的方法
May 05 PHP
PHP 应用容器化以及部署方法
Feb 12 PHP
PHP区块查询实现方法分析
May 12 PHP
php 解决扫描二维码下载跳转问题
Jan 13 #PHP
PHP使用递归算法无限遍历数组示例
Jan 13 #PHP
PHP字符串逆序排列实现方法小结【strrev函数,二分法,循环法,递归法】
Jan 13 #PHP
PHP使用strrev翻转中文乱码问题的解决方法
Jan 13 #PHP
使用php完成常见的文件上传功能(推荐)
Jan 13 #PHP
Yii2实现增删改查后留在当前页的方法详解
Jan 13 #PHP
PHP文件上传、客户端和服务器端加限制、抓取错误信息、完整步骤解析
Jan 12 #PHP
You might like
PHP utf-8编码问题,utf8编码,数据库乱码,页面显示输出乱码
2013/04/08 PHP
IIS6.0中配置php服务全过程解析
2013/08/07 PHP
php实现压缩合并js的方法【附demo源码下载】
2016/09/22 PHP
PHP信号处理机制的操作代码讲解
2019/04/19 PHP
基于PHP实现邮箱验证激活过程详解
2020/10/28 PHP
DHTML Slide Show script图片轮换
2008/03/03 Javascript
C#中TrimStart,TrimEnd,Trim在javascript上的实现
2011/01/17 Javascript
jquery实现的可隐藏重现的靠边悬浮层实例代码
2013/05/27 Javascript
ParseInt函数参数设置介绍
2014/01/02 Javascript
Node.js本地文件操作之文件拷贝与目录遍历的方法
2016/02/16 Javascript
各式各样的导航条效果css3结合jquery代码实现
2016/09/17 Javascript
JS正则表达式修饰符global(/g)用法分析
2016/12/27 Javascript
JQuery Ajax 异步操作之动态添加节点功能
2017/05/24 jQuery
简单实现JavaScript弹幕效果
2020/08/27 Javascript
利用Vue.js实现求职在线之职位查询功能
2017/07/03 Javascript
Vue.set()实现数据动态响应的方法
2018/02/07 Javascript
vue component 中引入less文件报错 Module build failed
2019/04/17 Javascript
vue 如何从单页应用改造成多页应用
2020/10/23 Javascript
[01:38]DOTA2 2015国际邀请赛中国区预选赛 Showopen
2015/06/01 DOTA
[04:15]DOTA2-DPC中国联赛 正赛 Ehome vs Aster 选手采访
2021/03/11 DOTA
为Python程序添加图形化界面的教程
2015/04/29 Python
Python绘制KS曲线的实现方法
2018/08/13 Python
python scipy求解非线性方程的方法(fsolve/root)
2018/11/12 Python
python数值基础知识浅析
2019/11/19 Python
python函数enumerate,operator和Counter使用技巧实例小结
2020/02/22 Python
详解Python 循环嵌套
2020/07/09 Python
Manjaro、pip、conda更换国内源的方法
2020/11/17 Python
HTML5如何实现元素拖拽
2016/03/11 HTML / CSS
介绍下Lucene建立索引的过程
2016/03/02 面试题
珍惜资源的建议书
2014/08/26 职场文书
与死神共舞观后感
2015/06/15 职场文书
元宵节晚会主持词
2015/07/01 职场文书
企业愿景口号
2015/12/25 职场文书
python小程序之飘落的银杏
2021/04/17 Python
总结Python变量的相关知识
2021/06/28 Python
python模拟浏览器 使用selenium进入好友QQ空间并留言
2022/04/12 Python