天天看點

wecenter二次開發系列(三)——多個wc架構同域網站共享cookie

由于項目需要,我們需要多個二級域名問答網站對整站的内容進行獨立管理和營運。

那麼,如何實作使用者在任何一個子站或主站登入登出統一步調呢?在這裡我們首先需要共享cookie,進而實作同域單點登入,統一生成.xxx.com下的cookie,使得主站和子站用生成的cookie進行使用者身份校驗。

主要涉及三個檔案:

system/core/user.php 讀取cookie并進行解碼

app/account/ajax.php 登入後設定cookie

models/account.php 設定cookie

具體的代碼修改分以下幾塊:

1.對于主站

改動:設定主站system/class/cls_http.inc.php中setcookie函數$domain為”.xxx.com”。
public static function set_cookie($name, $value = '', $expire = null, $path = '/', $domain = null, $secure = false, $httponly = false)
    {
        if (! $domain and G_COOKIE_DOMAIN)
        {
            $domain = G_COOKIE_DOMAIN;
        }
        $domain = '.xxx.com';

        return setcookie('jdn_' . $name, $value, $expire, $path, $domain, $secure, $httponly);
        //return setcookie(G_COOKIE_PREFIX . $name, $value, $expire, $path, $domain, $secure, $httponly);
    }
           

說明:由于不明的原因G_COOKIE_DOMAIN define無效,故設定cookie的時候直接指定域為.xxx.com

2.對于子站:

改動1:system/class/cls_http.inc.php

說明:二級域名擷取cookie必須保證名稱一緻,另外二級域名在生成cookie的時候同樣要指定域為.xxx.com。

代碼中注釋部分為代碼。

/*** 擷取 COOKIE
*
* @param $name*/
public static function get_cookie($name)
{
    // if (isset($_COOKIE[G_COOKIE_PREFIX . $name]))
    // {
        // return $_COOKIE[G_COOKIE_PREFIX . $name];
    // }

    if (isset($_COOKIE['jdn_' . $name]))
    {
        return $_COOKIE['jdn_' . $name];
    }

    return false;
}

/**
 * 設定 COOKIE
 *
 * @param $name
 * @param $value
 * @param $expire
 * @param $path
 * @param $domain
 * @param $secure
 * @param $httponly
 */
public static function set_cookie($name, $value = '', $expire = null, $path = '/', $domain = null, $secure = false, $httponly = false)
{
    if (! $domain and G_COOKIE_DOMAIN)
    {
        $domain = G_COOKIE_DOMAIN;
    }
    $domain = '.f1bang.com';

    return setcookie('jdn_' . $name, $value, $expire, $path, $domain, $secure, $httponly);
    //return setcookie(G_COOKIE_PREFIX . $name, $value, $expire, $path, $domain, $secure, $httponly);
}
           
改動2:/system/functions.inc.php 将使用者登入資訊編譯成 hash 字元串,用于發送 Cookie

這裡的G_COOKIE_HASH_KEY同樣需要指定為一級域名的hashkey=’fwtvfmbkzamtjyq’(具體需要調試檢視主站的hashkey确定,可能會有變動)

/**
 * 将使用者登入資訊編譯成 hash 字元串,用于發送 Cookie
 *
 * @param  string
 * @param  string
 * @param  string
 * @param  integer
 * @param  boolean
 * @return string
 */
function get_login_cookie_hash($user_name, $password, $salt, $uid, $hash_password = true)
{
    if ($hash_password)
    {
        $password = compile_password($password, $salt);
    }

    //$auth_hash_key = md5(G_COOKIE_HASH_KEY . $_SERVER['HTTP_USER_AGENT']);
    $auth_hash_key = md5('fwtvfmbkzamtjyq' . $_SERVER['HTTP_USER_AGENT']);

    return H::encode_hash(array(
        'uid' => $uid,
        'user_name' => $user_name,
        'password' => $password
    ), $auth_hash_key);
}
           
改動3:system/core/user.php 讀取cookie并進行解碼

說明:G_COOKIE_HASH_KEY如果主站的不一緻,必須指定一直,這裡為’fwtvfmbkzamtjyq’,另外還需指定cookie名jdn__user_login。

public function __construct()
{       
    if (AWS_APP::session()->client_info AND ! $_COOKIE['jdn__user_login'])
    {           
        unset(AWS_APP::session()->client_info);
    }

    if (! AWS_APP::session()->client_info AND $_COOKIE['jdn__user_login'])
    {
        //$auth_hash_key = md5(G_COOKIE_HASH_KEY . $_SERVER['HTTP_USER_AGENT']);
        $auth_hash_key = md5('fwtvfmbkzamtjyq' . $_SERVER['HTTP_USER_AGENT']);
        // 解碼 Cookie
        $sso_user_login = H::decode_hash($_COOKIE['jdn__user_login'], $auth_hash_key);     

        if ($sso_user_login['user_name'] AND $sso_user_login['password'] AND $sso_user_login['uid'])
        {               
            if (AWS_APP::model('account')->check_hash_login($sso_user_login['user_name'], $sso_user_login['password']))
            {               
                AWS_APP::session()->client_info['__CLIENT_UID'] = $sso_user_login['uid'];
                AWS_APP::session()->client_info['__CLIENT_USER_NAME'] = $sso_user_login['user_name'];
                AWS_APP::session()->client_info['__CLIENT_PASSWORD'] = $sso_user_login['password'];

                return true;
            }
        }

        return false;
    }
}
           

特别注意:這裡的‘jdn_’,’fwtvfmbkzamtjyq’可能會發生改變,具體可檢視浏覽器中cookie确定