用PHP实现SSO单点登录

419 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 6 月更文挑战」的第 20 天,点击查看活动详情
SSO英文全称Single Sign On,单点登录。SSO是在多个应用系统中,用户只需要登录一次就可以访问所有相互信任的应用系统。

它包括可以将这次主要的登录映射到其他应用中用于同一个用户的登录的机制。它是目前比较流行的企业业务整合的解决方案之一,下面我们来看看吧。

简单讲一下 SSO 单点登录系统的接入的原理,前提是系统本身有完善的用户认证功能,即基本的用户登录功能,那实现起来就很方便了。

SSO 登录请求接口往往是接口加上一个回调地址,访问这个地址会跳转到回调地址并带上一个 ticket 参数,拿着这个 ticket 参数再请求接口可以获取到用户信息,如果存在用户则自动登录,不存在就新增用户并登录。

实现单点登录(Single Sign-On,SSO)涉及到多个系统之间的身份认证和授权。在 PHP 中,你可以使用一些标准的协议和技术来实现 SSO,其中最常见的是使用基于令牌的认证。

下面是一个简单的示例,演示如何使用 PHP 实现 SSO 单点登录:

  1. 创建认证中心(Auth Center):这是负责处理用户认证和颁发令牌的中心系统。
<?php
// auth_center.php

// 验证用户凭证(例如用户名和密码),并生成令牌
function authenticate($username, $password) {
    // 在此处实现验证逻辑,例如查询数据库进行验证
    
    if ($username === 'admin' && $password === 'password') {
        // 生成令牌
        $token = generateToken($username);
        return $token;
    }
    
    return null;
}

// 生成令牌
function generateToken($username) {
    // 在此处生成令牌的逻辑,例如使用 JSON Web Token(JWT)
    // 这里只是一个简单示例,实际应用中需要使用更加安全的方式来生成令牌
    
    $payload = array(
        'username' => $username,
        'exp' => time() + 3600 // 令牌过期时间为 1 小时
    );
    
    $token = base64_encode(json_encode($payload));
    return $token;
}
?>
  1. 创建服务提供者(Service Provider):这是需要接入 SSO 的系统之一。
<?php
// service_provider.php

require 'auth_center.php';

// 获取认证中心生成的令牌
$token = $_GET['token'] ?? null;

// 验证令牌
function validateToken($token) {
    // 在此处验证令牌的有效性,例如解析 JWT 并检查签名
    
    if ($token) {
        // 这里只是一个简单示例,实际应用中需要使用更加安全的验证方式
        $decodedToken = json_decode(base64_decode($token), true);
        
        if ($decodedToken && $decodedToken['exp'] > time()) {
            // 令牌有效
            return true;
        }
    }
    
    return false;
}

// 检查令牌是否有效
if (validateToken($token)) {
    // 令牌有效,进行授权或其他操作
    
    echo 'Authorized!';
} else {
    // 令牌无效,跳转到认证中心进行登录
    
    $loginUrl = 'http://authcenter.example.com/login';
    header('Location: ' . $loginUrl);
    exit;
}
?>
  1. 创建认证中心登录页面(login.php):这是用户登录页面,负责收集用户凭证并验证。
<?php
// login.php

require 'auth_center.php';

// 处理登录请求
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
    $username = $_POST['username'] ?? null;
    $password = $_POST['password'] ?? null;

    // 验证用户凭证
    $token = authenticate($username, $password);
    
    if ($token) {
        // 重定向到服务提供者,并传递生成的令牌
        $serviceProviderUrl = 'http://serviceprovider.example.com';
        header('Location: ' . $serviceProviderUrl . '?token=' . $token);
        exit;
    } else {
        // 登录失败,显示错误信息
        echo 'Invalid username or password.';
    }
}
?>

<!-- 登录表单 -->
<form method="POST" action="">
    <label for="username">Username:</label>
    <input type="text" id="username" name="username" required>
    
    <label for="password">Password:</label>
    <input type="password" id="password" name="password" required>
    
    <button type="submit">Login</button>
</form>

请注意,以上示例是一个简化的实现,实际应用中还需要考虑到安全性和其他方面的细节。这里的示例使用了基于令牌的验证方式,但你也可以使用其他的认证协议和技术,如OAuth、SAML等,具体实现取决于你的需求和系统架构。