boxmoe_header_banner_img

Hello! 欢迎来到悠悠畅享网!

文章导读

PHP 应用间单点登录 (SSO) 实现:基于 Cookie 的解决方案


avatar
站长 2025年8月16日 6

PHP 应用间单点登录 (SSO) 实现:基于 Cookie 的解决方案

PHP 应用间单点登录 (SSO) 实现:基于 Cookie 的解决方案

在多个 PHP 应用之间实现单点登录 (SSO) 可以极大地提升用户体验。当用户在一个应用中登录后,无需再次登录即可访问其他应用。本文将介绍一种基于 Cookie 共享的简单实现方法,并通过 cURL 模拟登录,实现应用间的无缝切换。

核心思路

该方案的核心在于使用 cURL 模拟用户登录第一个应用,获取登录后的 Cookie 信息,然后将该 Cookie 信息传递给第二个应用,从而使第二个应用认为用户已经登录。

实现步骤

  1. 模拟登录第一个应用 (Symfony 应用)

    由于我们已经假设用户成功登录 Symfony 应用,所以这一步可以省略。关键在于确保 Symfony 应用正确设置了 Cookie,并且 Cookie 的作用域能够被第二个应用访问到。

    立即学习PHP免费学习笔记(深入)”;

  2. 使用 cURL 模拟登录第二个应用 (DokuWiki)

    以下代码演示了如何使用 cURL 模拟登录 DokuWiki 应用,并获取登录后的 Cookie 信息:

    <?php $path_cookie = dirname(__FILE__) . '/cookie.txt'; $script = curl_init();  curl_setopt($script, CURLOPT_URL, 'XXXXXdo=login&sectok='); // 替换为 DokuWiki 登录 URL curl_setopt($script, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; Linux x86_64)'); curl_setopt($script, CURLOPT_POST, true); curl_setopt($script, CURLOPT_POSTFIELDS, "u=XXXX&p=XXXX"); // 替换为 DokuWiki 用户名和密码 curl_setopt($script, CURLOPT_RETURNTRANSFER, true); curl_setopt($script, CURLOPT_SSL_VERIFYPEER, false); // 建议在生产环境中启用 SSL 验证 curl_setopt($script, CURLOPT_SSL_VERIFYHOST, false); // 建议在生产环境中启用 SSL 验证 curl_setopt($script, CURLOPT_CONNECTTIMEOUT, 120); curl_setopt($script, CURLOPT_TIMEOUT, 120); curl_setopt($script, CURLOPT_MAXREDIRS, 10); curl_setopt($script, CURLOPT_COOKIESESSION, true); curl_setopt($script, CURLOPT_COOKIEJAR, $path_cookie); // 将 Cookie 保存到文件 curl_setopt($script, CURLOPT_FOLLOWLOCATION, 1);  $connexion = curl_exec($script);  if (curl_errno($script)) {     echo 'cURL error: ' . curl_error($script); } else {     curl_setopt($script, CURLOPT_URL, 'XXXXX&do=admin'); // 替换为 DokuWiki 管理页面 URL     curl_setopt($script, CURLOPT_POST, true);     curl_setopt($script, CURLOPT_SSL_VERIFYPEER, false); // 建议在生产环境中启用 SSL 验证     curl_setopt($script, CURLOPT_SSL_VERIFYHOST, false); // 建议在生产环境中启用 SSL 验证     curl_setopt($script, CURLOPT_COOKIEFILE, $path_cookie); // 从文件读取 Cookie     curl_setopt($script, CURLOPT_POSTFIELDS, "");     $contenu = curl_exec($script);     curl_close($script);      if (curl_errno($script)) {         echo 'cURL error: ' . curl_error($script);     } else {         echo $contenu;     } } ?>

    代码解释:

    • curl_setopt($script, CURLOPT_URL, ‘XXXXXdo=login&sectok=’);:设置 DokuWiki 的登录 URL。需要替换 XXXXX 为实际的 URL。
    • curl_setopt($script, CURLOPT_POSTFIELDS, “u=XXXX&p=XXXX”);:设置 POST 请求的参数,包括用户名和密码。需要替换 XXXX 为实际的用户名和密码。
    • curl_setopt($script, CURLOPT_COOKIEJAR, $path_cookie);:将 cURL 会话中的 Cookie 保存到 cookie.txt 文件中。
    • curl_setopt($script, CURLOPT_COOKIEFILE, $path_cookie);:从 cookie.txt 文件中读取 Cookie,以便在后续请求中使用。
    • curl_setopt($script, CURLOPT_SSL_VERIFYPEER, false); 和 curl_setopt($script, CURLOPT_SSL_VERIFYHOST, false);:在开发环境中可以禁用 SSL 验证,但在生产环境中强烈建议启用。
  3. 解决 Cookie 会话丢失问题

    原代码中提到的 Cookie 会话丢失问题,通常是由于以下原因造成的:

    • Cookie 作用域不正确: 确保 Symfony 应用设置的 Cookie 的 domain 和 path 属性能够被 DokuWiki 应用访问到。通常,domain 应该设置为两个应用的共同父域名,path 应该设置为 /。
    • Cookie 名称冲突: 如果两个应用使用了相同的 Cookie 名称,可能会导致冲突。建议为每个应用使用不同的 Cookie 名称。
    • PHP 会话配置不一致: 确保两个应用的 session.cookie_domain 和 session.cookie_path 配置保持一致。

    解决方案:

    • 明确设置 Cookie 作用域: 在 Symfony 应用中,确保 Cookie 的 domain 和 path 属性设置正确。

    • 使用不同的 Cookie 名称: 避免两个应用使用相同的 Cookie 名称。

    • 配置 PHP 会话: 在 php.ini 文件中,或者使用 ini_set() 函数,确保两个应用的 session.cookie_domain 和 session.cookie_path 配置保持一致。例如:

      ini_set('session.cookie_domain', '.example.com'); // 替换为你的域名 ini_set('session.cookie_path', '/');
  4. 更安全的解决方案:

    以上方案虽然简单,但是将用户名和密码硬编码在代码中是不安全的。更安全的做法是:

    • 使用 OAuth 2.0 或 OpenID Connect: 这些协议提供了更安全、更标准的单点登录解决方案。
    • 使用共享数据库: 将用户认证信息存储在一个共享数据库中,两个应用可以访问该数据库进行用户认证。
    • 使用 JWT (JSON Web Token): 在用户登录 Symfony 应用后,生成一个 JWT,并将其传递给 DokuWiki 应用。DokuWiki 应用可以使用密钥验证 JWT 的有效性。

注意事项

  • 安全性: 在生产环境中,务必启用 SSL 验证,并避免将用户名和密码硬编码在代码中。
  • 错误处理: 完善错误处理机制,例如检查 cURL 请求是否成功,以及 DokuWiki 是否成功登录。
  • Cookie 过期时间: 确保 Cookie 的过期时间设置合理,避免用户频繁重新登录。

总结

本文介绍了一种基于 Cookie 共享的简单 PHP 应用单点登录实现方法。虽然该方法简单易懂,但在安全性方面存在一些不足。在实际应用中,建议根据具体情况选择更安全、更标准的单点登录解决方案,例如 OAuth 2.0、OpenID Connect 或 JWT。通过合理配置 Cookie 作用域、避免 Cookie 名称冲突,以及保持 PHP 会话配置一致,可以有效解决 Cookie 会话丢失问题。



评论(已关闭)

评论已关闭