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 相关文章推荐
php实现的在线人员函数库
Apr 09 PHP
PHP 简单数组排序实现代码
Aug 05 PHP
在PHP模板引擎smarty生成随机数的方法和math函数详解
Apr 24 PHP
Thinkphp搭建包括JS多语言的多语言项目实现方法
Nov 24 PHP
PHP实现根据银行卡号判断银行
Apr 29 PHP
PHP对XML内容进行修改和删除实例代码
Oct 26 PHP
thinkphp实现把数据库中的列的值存到下拉框中的方法
Jan 20 PHP
php数据库的增删改查 php与javascript之间的交互
Aug 31 PHP
Laravel 微信小程序后端实现用户登录的示例代码
Nov 26 PHP
浅析PHP中的 inet_pton 网络函数
Dec 16 PHP
php实现微信和支付宝支付的示例代码
Aug 11 PHP
Swoole扩展的6种模式深入详解
Mar 04 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中数组定义的几种方法
2013/09/01 PHP
Laravel 修改验证异常的响应格式实例代码详解
2020/05/25 PHP
jQuery TextBox自动完成条
2009/07/22 Javascript
javascript实现促销倒计时+fixed固定在底部
2013/09/18 Javascript
JavaScript中的函数重载深入理解
2014/08/04 Javascript
让人蛋疼的JavaScript语法特性
2014/09/30 Javascript
Json实现异步请求提交评论无需跳转其他页面
2014/10/11 Javascript
前端必备神器 Snap.svg 弹动效果
2014/11/10 Javascript
javascript中定义类的方法汇总
2014/12/28 Javascript
javascript继承的六大模式小结
2015/04/13 Javascript
jQuery实现的模拟弹出窗口功能示例
2016/11/24 Javascript
BootStrap Table复选框默认选中功能的实现代码(从数据库获取到对应的状态进行判断是否为选中状态)
2017/07/11 Javascript
React组件refs的使用详解
2018/02/09 Javascript
深入了解JavaScript 私有化
2019/05/30 Javascript
JavaScript深入V8引擎以及编写优化代码的5个技巧
2019/06/24 Javascript
详解如何在JS代码中消灭for循环
2019/12/11 Javascript
微信小程序实现横向滚动导航栏效果
2019/12/12 Javascript
在Vue中使用HOC模式的实现
2020/08/23 Javascript
微信小程序实现自定义动画弹框/提示框的方法实例
2020/11/06 Javascript
[14:00]DOTA2国际邀请赛史上最长大战 赛后专访B神
2013/08/10 DOTA
python以环状形式组合排列图片并输出的方法
2015/03/17 Python
python实现将html表格转换成CSV文件的方法
2015/06/28 Python
Python数组遍历的简单实现方法小结
2016/04/27 Python
详解Python传入参数的几种方法
2019/05/16 Python
python实现爬取百度图片的方法示例
2019/07/06 Python
Python3 tkinter 实现文件读取及保存功能
2019/09/12 Python
python基于FTP实现文件传输相关功能代码实例
2019/09/28 Python
Python依赖包迁移到断网环境操作
2020/07/13 Python
Python3爬虫里关于识别微博宫格验证码的知识点详解
2020/07/30 Python
英国家喻户晓的高街品牌:River Island
2017/11/28 全球购物
Baby Tulai澳大利亚:美国婴儿背带品牌
2018/10/15 全球购物
CSS实现fullpage.js全屏滚动效果的示例代码
2021/03/24 HTML / CSS
公司贷款承诺书
2014/05/30 职场文书
中文专业求职信
2014/06/20 职场文书
用python批量解压带密码的压缩包
2021/05/31 Python
el-form每行显示两列底部按钮居中效果的实现
2022/08/05 HTML / CSS