Wordpress中的SSO(Single Sign-On)登录系统

社区话题 wordpress开发 Wordpress中的SSO(Single Sign-On)登录系统

标签: 

正在查看 0 条回复
  • 作者
    帖子
    • #393

      追光
      管理员

      下面是对Wordpress的 SSO(Single Sign-On)登录系统实现的完整中文说明与注释教程,便于你自己维护、或让其他开发者快速理解并接入。


      ? 背景与目标

      这是一个 WordPress 基于 JWT(JSON Web Token)实现的 SSO 跨子域登录系统,适用于主站和多个子站共享登录状态。

      例如:main.newvfx.com 登录后,forum.newvfx.comdocs.newvfx.com 无需再次登录。


      ? 功能概览

      • 登录后生成 JWT Token 并写入跨域 Cookie(.newvfx.com)。

      • 子站可通过读取此 Cookie 自动识别用户身份(推荐配合 JWT Auth 插件)。

      • 支持自动同步 nicknamedisplay_namecellphone头像

      • 自动清除登录 Cookie,避免脏状态。

      • 保持主子站登录状态一致(可选,含安全登出)。


      ✅ 代码详解与注释

      // ┌────────────────────────────────────┐
      // │         ? ️SSO登录 jisongbin        │
      // └────────────────────────────────────┘
      
      
      // ✅ 设置 JWT 密钥(主子站保持一致)用于加密 token
      define('JWT_AUTH_SECRET_KEY', 'a0d572e3fc3f45389e91c93e891b7efb6a7f4471c21');
      
      // ✅ 开启跨域请求支持(允许 REST API 跨域调用)
      define('JWT_AUTH_CORS_ENABLE', true);

      ? 用户信息同步(从 JWT token 提取字段并写入 WordPress 用户资料)

      function sync_user_meta_from_token($user, $token_payload) {
          if (!$user || is_wp_error($user)) return;
      
          // ✅ 同步 display_name
          if (!empty($token_payload['data']['user']['display_name'])) {
              wp_update_user([
                  'ID' => $user->ID,
                  'display_name' => sanitize_text_field($token_payload['data']['user']['display_name']),
              ]);
          }
      
          // ✅ 同步 nickname
          if (!empty($token_payload['data']['user']['nickname'])) {
              update_user_meta($user->ID, 'nickname', sanitize_text_field($token_payload['data']['user']['nickname']));
          }
      
          // ❌ 这段代码无效(未使用变量 $column_name 和 $user_id),可删除
          if ($column_name === 'cellphone') {
              $phone = get_user_meta($user_id, 'cellphone', true);
              return $phone ?: '—';
          }
      }

      ? 登录时生成 Token 并存储在 Cookie(.newvfx.com 域名下)

      add_action('wp_login', function ($user_login, $user) {
          // 密钥(必须与子站一致)
          $secret_key = 'a0d572e3fc3f45389e91c93e891b7efb6a7f4471c21';
      
          // 获取头像链接
          $avatar_url = get_avatar_url($user->ID, ['size' => 96]);
      
          // 创建 JWT Payload
          $payload = array(
              'iss' => get_site_url(),              // 签发站点
              'iat' => time(),                      // 签发时间
              'exp' => time() + HOUR_IN_SECONDS,    // 过期时间(1小时)
              'data' => array(
                  'user' => array(
                      'user_login'   => $user->user_login,
                      'user_email'   => $user->user_email,
                      'ID'           => $user->ID,
                      'display_name' => $user->display_name,
                      'nickname'     => get_user_meta($user->ID, 'nickname', true),
                      'cellphone'    => get_user_meta($user->ID, 'cellphone', true),
                      'avatar'       => $avatar_url
                  )
              )
          );
      
          // ✅ 加载 JWT 类库(需安装 firebase/php-jwt)
          if (!class_exists('Firebase\\JWT\\JWT')) {
              require_once ABSPATH . 'vendor/autoload.php';
          }
      
          // ✅ 编码为 JWT Token
          $jwt = \Firebase\JWT\JWT::encode($payload, $secret_key, 'HS256');
      
          // ✅ 设置跨子域 cookie(secure + httponly)
          setcookie('main_jwt_token', $jwt, time() + HOUR_IN_SECONDS, '/', '.newvfx.com', true, true);
      
      }, 10, 2);

      ? 退出登录时,清除跨域 cookie

      add_action('wp_logout', function () {
          setcookie('main_jwt_token', '', time() - 3600, '/', '.newvfx.com', true, true);
      });

      ? 子站监听主站退出状态(可选)

      /*
      add_action('init', function () {
          if (is_user_logged_in()) {
              // 没有 JWT token(说明主站登出)
              if (empty($_COOKIE['main_jwt_token'])) {
                  wp_logout(); // 自动登出
                  wp_redirect(home_url()); // 重定向
                  exit;
              }
          }
      });
      */

      说明:如果子站启用了第三方登录(如 Open Social),建议不要启用此同步登出逻辑,防止误登出。


      ? 要求依赖

      composer require firebase/php-jwt
      • 若要让子站识别 Token 并自动登录,可使用插件 JWT Auth 或自行实现验证逻辑。


      ? 推荐用法搭配

      站点角色

      操作方式

      描述

      主站

      负责登录、生成并下发 JWT cookie

      setcookie(.newvfx.com) 写入主 Cookie

      子站

      从 cookie 获取 JWT,自动验证登录

      可调用 REST API 登录,或同步到 WP 会话


      ✅ 示例:在子站判断登录状态

      你可以在子站 functions.php 中加入:

      if (!is_user_logged_in() && isset($_COOKIE['main_jwt_token'])) {
          // 向主站发起 REST 请求验证 Token,并登录当前用户
          // 或解析 JWT 获取 user 信息并创建登录会话
      }

      ✅ 总结

      功能点

      是否已实现

      说明

      登录生成 JWT

      使用 wp_login 钩子

      跨子域共享 Cookie

      .newvfx.com 有效

      用户资料同步

      支持 nickname、display_name、cellphone等

      登出清除 Token

      wp_logout 钩子

      子站强制退出(可选)

      ✅(注释)

      若主站退出,子站也退出

正在查看 0 条回复
  • 在下方一键注册,登录后就可以回复啦。