当前位置:首页 > PHP

php 实现单点登录

2026-01-14 13:05:53PHP

PHP 实现单点登录的方法

单点登录(SSO)允许用户通过一次登录访问多个相互信任的系统。以下是基于 PHP 的实现方案:

基于共享 Session 的方案

在同一个主域名下的子域名间可以通过共享 Session 实现 SSO。PHP 默认情况下 Session 的 Cookie 作用域是当前域名,可以通过修改 session.cookie_domain 配置实现跨子域名共享。

// 设置 Session Cookie 的作用域为 .example.com
ini_set('session.cookie_domain', '.example.com');
session_start();

各个子域名的应用需要统一 Session 存储,例如使用 Redis 作为共享存储:

ini_set('session.save_handler', 'redis');
ini_set('session.save_path', 'tcp://127.0.0.1:6379');

基于 Token 的方案

对于跨域场景,可以使用 Token 方案。认证中心颁发 Token,各应用系统验证 Token 的有效性。

  1. 用户访问系统 A,未登录则跳转至认证中心
  2. 认证中心验证用户身份,生成 Token 并重定向回系统 A
  3. 系统 A 携带 Token 向认证中心验证
  4. 认证通过后建立本地 Session

Token 生成示例:

php 实现单点登录

function generateToken($userId) {
    $secret = 'your_secret_key';
    $header = base64_encode(json_encode(['alg' => 'HS256', 'typ' => 'JWT']));
    $payload = base64_encode(json_encode(['user_id' => $userId, 'exp' => time() + 3600]));
    $signature = hash_hmac('sha256', "$header.$payload", $secret);
    return "$header.$payload.$signature";
}

基于 OAuth 2.0 的方案

OAuth 2.0 是标准的授权协议,可用于实现 SSO。常用库包括 league/oauth2-client

安装库:

composer require league/oauth2-client

客户端实现示例:

php 实现单点登录

use League\OAuth2\Client\Provider\GenericProvider;

$provider = new GenericProvider([
    'clientId'                => 'your_client_id',
    'clientSecret'            => 'your_client_secret',
    'redirectUri'             => 'https://your-app.com/callback',
    'urlAuthorize'            => 'https://sso-provider.com/authorize',
    'urlAccessToken'          => 'https://sso-provider.com/token',
    'urlResourceOwnerDetails' => 'https://sso-provider.com/resource'
]);

// 获取授权码
if (!isset($_GET['code'])) {
    $authUrl = $provider->getAuthorizationUrl();
    $_SESSION['oauth2state'] = $provider->getState();
    header('Location: '.$authUrl);
    exit;
}

// 获取访问令牌
try {
    $accessToken = $provider->getAccessToken('authorization_code', [
        'code' => $_GET['code']
    ]);

    // 使用令牌获取用户信息
    $resourceOwner = $provider->getResourceOwner($accessToken);
    $user = $resourceOwner->toArray();

    // 建立本地会话
    $_SESSION['user'] = $user;
} catch (\Exception $e) {
    exit('登录失败: '.$e->getMessage());
}

基于 SAML 的方案

SAML 是企业级 SSO 常用协议,可使用 simplesamlphp 库实现。

安装 SimpleSAMLphp:

composer require simplesamlphp/simplesamlphp

配置 SP (Service Provider):

require_once('vendor/simplesamlphp/lib/_autoload.php');
$auth = new SimpleSAML_Auth_Simple('default-sp');

if (!$auth->isAuthenticated()) {
    $auth->login();
}

$attributes = $auth->getAttributes();
$_SESSION['user'] = $attributes;

安全注意事项

  1. 所有方案都应使用 HTTPS 确保传输安全
  2. Token 应设置合理的过期时间
  3. 敏感操作需要重新验证
  4. 实现完善的注销机制,包括各系统的会话清除

注销实现

全局注销需要清除所有系统的会话:

// 认证中心注销
session_destroy();

// 通知各子系统注销
foreach ($subSystems as $system) {
    file_get_contents("$system/logout?token=$globalToken");
}

以上方案可根据实际需求选择或组合使用,企业级环境推荐 OAuth 2.0 或 SAML 方案。

标签: 单点php
分享给朋友:

相关文章

php队列的实现

php队列的实现

PHP队列的实现方式 PHP中实现队列功能可以通过多种方式,根据需求选择适合的方案: 使用数组实现基础队列 PHP数组本身支持队列操作,利用array_push和array_shift函数: $q…

php 伪静态实现

php 伪静态实现

PHP 伪静态实现方法 伪静态(URL Rewrite)是一种通过服务器配置将动态URL转换为静态URL的技术,提升URL的可读性和SEO效果。以下是几种常见的实现方式: 使用Apache的mod_…

php变量的实现

php变量的实现

PHP变量的实现机制 PHP变量的实现基于Zend引擎的底层数据结构。核心结构体zval用于存储变量类型和值,其设计允许动态类型转换和高效内存管理。 zval结构体 PHP变量通过zval结构体实现…

php 链表实现

php 链表实现

在 PHP 中实现链表可以通过类来模拟链表节点(Node)和链表(LinkedList)结构。以下是链表的完整实现示例,包含基础操作如插入、删除、遍历等。 链表节点类(Node) 链表的基本单元是节…

php实现短信验证

php实现短信验证

PHP实现短信验证的步骤 选择合适的短信服务提供商 国内常见的短信服务提供商包括阿里云短信、腾讯云短信、云片等。注册账号并获取API密钥和签名模板是第一步。这些平台通常提供详细的开发文档和SDK。…