首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

UCenter 通信原理深度解析:同步登入流程、雙向回調與 Cookie 機制

     編輯:PHP 相關知識

UCenter 通信原理深度解析:同步登入流程、雙向回調與 Cookie 機制

UCenter(Discuz! 核心用戶中心)實現多應用單點登入(SSO)的核心機制是「中心廣播 + 客戶端回調 + Cookie 共享」。本文拆解完整通信鏈路:從應用登入驗證、UCenter 廣播通知、各應用 uc.php 回調處理、_authcode 加密解密、_setcookie 寫入 Cookie,到跨域同步登入的實現細節。

完整通信時序圖


用戶訪問應用 A (Discuz) 登入
       ↓
應用 A logging.php → uc_user_login($username, $password) 驗證
       ↓ 成功
應用 A uc_client/client.php → uc_user_synlogin($uid)
       ↓
uc_api_post('user', 'synlogin', ['uid'=>$uid]) → HTTP POST 到 UCenter index.php
       ↓
UCenter index.php 解析 model=user, action=synlogin
       ↓
UCenter control/user.php → onsynlogin() 遍歷「開啟同步登入」的應用列表
       ↓
對每個應用輸出 <script src="APP_URL/api/uc.php?time=...&code=..." reload="1"></script>
       ↓ 瀏覽器執行 JS
應用 B/C/D 的 api/uc.php 接收 GET 參數
       ↓
uc.php → synlogin() → _authcode($code, 'DECODE', UC_KEY) 解密
       ↓ 獲得 uid, username 等
_setcookie('sid', $auth, ...) 寫入應用域名下 Cookie
       ↓
用戶後續訪問應用 B/C/D → 攜帶 Cookie → 自動識別登入狀態

關鍵檔案與職責

檔案角色核心函數
logging.php應用登入入口uc_user_login()
uc_client/client.php客戶端 SDKuc_user_synlogin(), uc_api_post()
UCenter/index.php中心入口/分發路由到 control/user.php
UCenter/control/user.php業務邏輯onsynlogin() 廣播 JS
應用/api/uc.php回調入口synlogin(), _authcode(), _setcookie()

核心代碼片段

1. 應用發起同步登入

<?php
include './config.inc.php';
include './uc_client/client.php';

$uid = uc_user_login('kyee', '123456');
if ($uid > 0) {
    setcookie('username', 'kyee', time()+86400);
    echo uc_user_synlogin($uid); // 輸出一堆 <script src=...>
    echo '登入成功';
}
?>

2. UCenter 廣播 JS(onsynlogin 簡化)

<?php
// UCenter control/user.php
public function onsynlogin($uid) {
    $apps = $this->getAppsWithSynlogin(); // 從緩存/DB 讀取
    foreach ($apps as $app) {
        $code = _authcode("uid=$uid", 'ENCODE', $app['authkey']);
        $url = $app['url'] . "/api/uc.php?time=" . time() . "&code=" . urlencode($code);
        echo '<script type="text/javascript" src="' . $url . '" reload="1"></script>';
    }
}
?>

3. 應用回調處理(api/uc.php)

<?php
// 應用 api/uc.php
function synlogin($get) {
    $code = $get['code'];
    $data = _authcode($code, 'DECODE', UC_KEY); // 解密得到 "uid=123"
    parse_str($data, $arr);
    $uid = $arr['uid'];

    // 業務邏輯:查找/建立本地用戶、寫入 Session、設定 Cookie
    $user = getUserByUid($uid);
    if ($user) {
        _setcookie('auth', _authcode($user['id'] . "\t" . $user['password'], 'ENCODE'), 86400);
    }
}
?>

4. 加密核心 _authcode(簡化版)

<?php
function _authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
    $key = md5($key);
    if ($operation == 'DECODE') {
        $string = base64_decode($string);
        // ... XOR 解密邏輯 ...
    } else {
        // ... XOR 加密 + base64_encode ...
    }
    return $result;
}
?>

同步登入本質:跨域 Cookie 植入

瀏覽器同源策略禁止跨域寫 Cookie。UCenter 巧妙利用 <script src="跨域URL"> **不受同源策略限制**的特性:

  1. UCenter 輸出一堆 `
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved