WIKI使用導(dǎo)航
站長(zhǎng)百科導(dǎo)航
站長(zhǎng)專題
- 網(wǎng)站推廣
- 網(wǎng)站程序
- 網(wǎng)站賺錢
- 虛擬主機(jī)
- cPanel
- 網(wǎng)址導(dǎo)航專題
- 云計(jì)算
- 微博營(yíng)銷
- 虛擬主機(jī)管理系統(tǒng)
- 開(kāi)放平臺(tái)
- WIKI程序與應(yīng)用
- 美國(guó)十大主機(jī)
Discuz:Discuz!PassPort接口技術(shù)文檔
Discuz! 6.0|Discuz! 6.0安裝|Discuz! 6.0使用|Discuz! 6.0風(fēng)格模板|Discuz! 6.0插件|Discuz! 6.0升級(jí)|Discuz! 6.0開(kāi)發(fā)|Discuz! 6.0 FAQ |
Discuz! Passport 接口技術(shù)文檔
- 從 Discuz! 4.0.0 RC4 版本開(kāi)始,Discuz! 內(nèi)嵌了一個(gè)獨(dú)特的 Passport(通行證) 接口,利用此接口,用戶將很容易將論壇與其他應(yīng)用程序整合,而實(shí)現(xiàn)統(tǒng)一登錄與退出、用戶數(shù)據(jù)共享、積分同步等功能??梢哉系膽?yīng)用程序包括內(nèi)容管理系統(tǒng)(CMS)、商城系統(tǒng)、游戲系統(tǒng)等等,如您對(duì)這方面功能有興趣或有需求,請(qǐng)繼續(xù)閱讀本文檔。
Discuz! Passport 的優(yōu)點(diǎn)
Discuz! Passport 系統(tǒng)使用了 Discuz! 獨(dú)有的技術(shù),并不等同于以往使用過(guò)的一些方法,與傳統(tǒng)的實(shí)現(xiàn)方式相比,具備(不限于)以下優(yōu)勢(shì):
- 基于私有密匙的低相關(guān)性可逆加密算法,配合 MD5 校檢碼技術(shù),使得暴力破解或偽造幾乎不可能。
- 應(yīng)用程序可與論壇放置于不同的服務(wù)器及不同的域名下??苫诓煌?a href="/wiki/%E6%93%8D%E4%BD%9C%E7%B3%BB%E7%BB%9F" title="操作系統(tǒng)">操作系統(tǒng)、不同程序語(yǔ)言和不同數(shù)據(jù)庫(kù)平臺(tái),具備真正的平臺(tái)無(wú)關(guān)性。
- 不需要任何形式的數(shù)據(jù)庫(kù)連接、或強(qiáng)制把兩套應(yīng)用程序的數(shù)據(jù)放在同一數(shù)據(jù)庫(kù)甚至同一數(shù)據(jù)表中。論壇與應(yīng)用程序都有各自的用戶數(shù)據(jù)表,只是在需要時(shí)進(jìn)行無(wú)縫同步操作。
- 對(duì)應(yīng)用程序的代碼改動(dòng)簡(jiǎn)便易行,可最快速的完成應(yīng)用程序與論壇間的整合。
Discuz! Passport 的局限
您在開(kāi)始利用 Discuz! Passport 進(jìn)行二次開(kāi)發(fā)時(shí),需要了解這個(gè)系統(tǒng)的局限性,以對(duì)未來(lái)的工作進(jìn)行正確的評(píng)估與安排。
- 只能工作在用戶密碼不加密、可逆加密或 MD5 加密的情況下,否則論壇后臺(tái)無(wú)法登錄。
- 只能與一種應(yīng)用程序關(guān)聯(lián),即二方關(guān)聯(lián)。不能實(shí)現(xiàn)三方關(guān)聯(lián)或與更多的應(yīng)用程序進(jìn)行關(guān)聯(lián)。
- 應(yīng)用程序需具有獨(dú)立的注冊(cè)、登錄、退出頁(yè)面和鏈接,否則需要自行修改論壇中的相應(yīng)表單或程序。
- 由于論壇的注冊(cè)人數(shù)可能很多,例如百萬(wàn)級(jí)以上,且應(yīng)用程序和論壇間的用戶數(shù)據(jù)是同步的,因此要求應(yīng)用程序能夠穩(wěn)定的負(fù)載大量用戶的訪問(wèn)。
Discuz! Passport 原理與流程
假設(shè)已設(shè)置如下變量或參數(shù)
- 掛接 Discuz! Passport 的應(yīng)用程序假設(shè)為一套 PHP 語(yǔ)言編寫的 CMS 系統(tǒng)
- Discuz! 的 URL 為 http://www.myforums.com
- 應(yīng)用程序的 URL 為 http://www.mywebsite.com
- 應(yīng)用程序的注冊(cè)頁(yè)面為 http://www.mywebsite.com/register.php
- 應(yīng)用程序的登錄頁(yè)面為 http://www.mywebsite.com/login.php?action=login
- 應(yīng)用程序的退出頁(yè)面為 http://www.mywebsite.com/login.php?action=logout
開(kāi)啟通行證后的用戶登錄流程
- 如果用戶在論壇點(diǎn)擊“登錄”,則轉(zhuǎn)向到事先設(shè)置好的應(yīng)用程序登錄頁(yè)面(http://www.mywebsite.com/login.php?action=login),并在登錄頁(yè)面的 URL 中加入?yún)?shù) forward(加入 forward 后的鏈接例如 http://www.mywebsite.com/login.php?action=login&forward=http://www.myforums.com/index.php),用于在登錄后將用戶導(dǎo)向到指定的 URL。
- 應(yīng)用程序收到此請(qǐng)求后,按照慣例生成表單,并增加一個(gè)表單變量 ,將 GET 方式傳遞過(guò)來(lái)的 forward 參數(shù)通過(guò)表單進(jìn)行傳遞。
- 用戶在應(yīng)用程序的表單中填寫登錄信息,并提交到應(yīng)用程序的登錄驗(yàn)證程序。應(yīng)用程序驗(yàn)證用戶提交的用戶名和密碼的合法性:
- 如果不通過(guò):提示用戶名密碼錯(cuò)誤,要求其返回上一頁(yè)重新填寫。
- 如果通過(guò),需要進(jìn)行如下操作:
- 設(shè)置自身 Cookie 或 Session,使得應(yīng)用程序自身處于登錄狀態(tài)。
- 檢查表單中是否提交了 forward 變量,如有,則意味著登錄請(qǐng)求可能是由論壇而來(lái),將此變量傳遞到后面的請(qǐng)求中。如沒(méi)有,自行生成 forward 變量,使得論壇登錄后能夠跳轉(zhuǎn)回到應(yīng)用程序中。
- 通過(guò) header('Location: http://www.myforums.com/api/passport.php?action=login&auth=xxx&forward=http://yyy&verify=zzz') 的方式,將登錄請(qǐng)求傳遞到論壇進(jìn)行處理。其中 auth 用來(lái)將用戶信息與資料以特定的格式,加密傳遞給論壇,forward 用于告知論壇 Passport API 完成自身操作后轉(zhuǎn)向到的 URL 地址,verify 用于驗(yàn)證前面兩個(gè)變量的有效性。auth、forward、verify 格式與結(jié)構(gòu)將在后面進(jìn)行說(shuō)明。
- Discuz! Passport API 在接收到由應(yīng)用程序通過(guò) header() 提交過(guò)來(lái)的請(qǐng)求后,進(jìn)行如下操作:
- 根據(jù) verify 判斷 auth 和 forward 變量是否合法,如合法則繼續(xù),否則終止。
- 將 auth 根據(jù)既定算法解密,并還原成數(shù)組,數(shù)組的內(nèi)容與格式將在后面進(jìn)行說(shuō)明。根據(jù)數(shù)組中的內(nèi)容,檢查此用戶是否存在。如存在,則根據(jù)上述數(shù)組中的內(nèi)容 UPDATE 論壇中相應(yīng)的用戶資料。如不存在,則使用數(shù)組中的信息 INSERT 到論壇用戶資料表中。
- 論壇設(shè)置 Cookie 或 Session,使得論壇自身處于登錄狀態(tài)。
- 根據(jù)應(yīng)用程序反饋的 forward 值,通過(guò) header('Location: http://xxx') 的形式將頁(yè)面跳轉(zhuǎn)到 forward 變量指定的 URL。
- 至此,登錄流程結(jié)束
開(kāi)啟通行證后的用戶退出流程
- 如果用戶在論壇點(diǎn)擊“退出”,則轉(zhuǎn)向到事先設(shè)置好的應(yīng)用程序退出頁(yè)面(http://www.mywebsite.com/login.php?action=logout),并在登錄頁(yè)面的 URL 中加入?yún)?shù) forward(例如 http://www.mywebsite.com/login.php?action=login&forward=http://www.myforums.com/index.php),用于在退出后將用戶導(dǎo)向到指定的 URL。
- 應(yīng)用程序收到此請(qǐng)求后,清除自身 Cookie 或 Session,使得應(yīng)用程序自身處于非登錄狀態(tài)。
- 檢查是否提交了 forward 變量,如有,則意味著登錄請(qǐng)求可能是由論壇而來(lái),將此變量傳遞到后面的請(qǐng)求中。如沒(méi)有,自行生成 forward 變量,使得論壇登錄后能夠跳轉(zhuǎn)回到應(yīng)用程序中。
- 通過(guò) header('Location: http://www.myforums.com/api/passport.php?action=logout&forward=http://yyy&verify=zzz') 的方式,將退出請(qǐng)求傳遞到論壇進(jìn)行處理。其中 forward 用于告知論壇 Passport API 完成自身操作后轉(zhuǎn)向到的 URL 地址,verify 用于驗(yàn)證 forward 變量的有效性。forward、verify 格式與結(jié)構(gòu)將在后面進(jìn)行說(shuō)明。
- Discuz! Passport API 在接收到由應(yīng)用程序通過(guò) header() 提交過(guò)來(lái)的請(qǐng)求后,進(jìn)行如下操作:
- 根據(jù) verify 判斷 forward 變量是否合法,如合法則繼續(xù),否則終止。
- 清楚論壇的 Cookie 或 Session,使得論壇自身處于非登錄狀態(tài)。
- 根據(jù)應(yīng)用程序反饋的 forward 值,通過(guò) header('Location: http://xxx') 的形式將頁(yè)面跳轉(zhuǎn)到 forward 變量指定的 URL。
- 至此,退出流程結(jié)束。
開(kāi)啟通行證后的用戶注冊(cè)流程
- 如果用戶在論壇點(diǎn)擊“注冊(cè)”,則轉(zhuǎn)向到事先設(shè)置好的應(yīng)用程序注冊(cè)頁(yè)面(http://www.mywebsite.com/register.php),并在注冊(cè)頁(yè)面的 URL 中加入?yún)?shù) forward(例如 http://www.mywebsite.com/register.php?forward=http://www.myforums.com/index.php),用于在注冊(cè)后將用戶導(dǎo)向到指定的 URL
- 應(yīng)用程序收到此請(qǐng)求后,按照慣例生成表單,并增加一個(gè)表單變量 ,將 GET 方式傳遞過(guò)來(lái)的 forward 參數(shù)通過(guò)表單進(jìn)行傳遞
- 用戶在應(yīng)用程序的表單中填寫注冊(cè)信息,并提交到應(yīng)用程序的注冊(cè)驗(yàn)證程序。應(yīng)用程序驗(yàn)證用戶提交信息的完整性和合法性:
- 如果不通過(guò):提示其問(wèn)題所在,要求其返回上一頁(yè)重新填寫
- 如果通過(guò),需要進(jìn)行如下操作:
- 將用戶資料插入到應(yīng)用程序自身用戶數(shù)據(jù)庫(kù)中
- 設(shè)置自身 Cookie 或 Session,使得應(yīng)用程序自身處于登錄狀態(tài)
- 檢查表單中是否提交了 forward 變量,如有,則意味著注冊(cè)請(qǐng)求可能是由論壇而來(lái),將此變量傳遞到后面的請(qǐng)求中。如沒(méi)有,自行生成 forward 變量,使得論壇注冊(cè)后能夠跳轉(zhuǎn)回到應(yīng)用程序中
- 通過(guò) header('Location: http://www.myforums.com/api/passport.php?action=login&auth=xxx&forward=http://yyy&verify=zzz') 的方式,將注冊(cè)請(qǐng)求傳遞到論壇進(jìn)行處理。其中 auth 用來(lái)將用戶信息與資料以特定的格式,加密傳遞給論壇,forward 用于告知論壇 Passport API 完成自身操作后轉(zhuǎn)向到的 URL 地址,verify 用于驗(yàn)證前面兩個(gè)變量的有效性。auth、forward、verify 格式與結(jié)構(gòu)將在后面進(jìn)行說(shuō)明
- Discuz! Passport API 在接收到由應(yīng)用程序通過(guò) header() 提交過(guò)來(lái)的請(qǐng)求后,進(jìn)行如下操作:
- 根據(jù) verify 判斷 auth 和 forward 變量是否合法,如合法則繼續(xù),否則終止
- 將 auth 根據(jù)既定算法解密,并還原成數(shù)組,數(shù)組的內(nèi)容與格式將在后面進(jìn)行說(shuō)明。根據(jù)數(shù)組中的內(nèi)容,檢查此用戶是否存在。如存在,則根據(jù)上述數(shù)組中的內(nèi)容 UPDATE 論壇中相應(yīng)的用戶資料。如不存在,則使用數(shù)組中的信息 INSERT 到論壇用戶資料表中
- 論壇設(shè)置 Cookie 或 Session,使得論壇自身處于登錄狀態(tài)
- 根據(jù)應(yīng)用程序反饋的 forward 值,通過(guò) header('Location: http://xxx') 的形式將頁(yè)面跳轉(zhuǎn)到 forward 變量指定的 URL
- 至此,注冊(cè)流程結(jié)束
本部分中,加下劃線顯示的部分,是需要對(duì)您的應(yīng)用程序進(jìn)行更改的部分,事實(shí)上,這部分更改會(huì)非常容易和方便。
Discuz! Passport 參數(shù)規(guī)格與加密方式
私有密匙(passport_key)
- 由于一些關(guān)鍵參數(shù)采用了 GET 方式進(jìn)行傳遞,即便兩次 header 跳轉(zhuǎn)并不會(huì)直接將鏈接顯示在外面,但我們?nèi)匀粚?duì)關(guān)鍵的參數(shù)進(jìn)行了加密,私有密匙共有兩個(gè)作用:其一是供下面提到的可逆加密算法(AzDGCrypt)進(jìn)行數(shù)據(jù)的加解密。其二是生成不可逆驗(yàn)證字串(verify),以防止關(guān)鍵信息被偽造。
- 在啟用 Discuz! Passort 后,您需要在應(yīng)用程序和 Discuz! 后臺(tái)配置兩處私有密匙,這兩處的內(nèi)容必須完全相同,這樣應(yīng)用程序和論壇之間才能正常通信。私有密匙決定了加密算法的強(qiáng)度,因此密匙長(zhǎng)度請(qǐng)不要小于 10 個(gè)字節(jié),并包含字母、數(shù)字和符號(hào),以保證系統(tǒng)的安全。
加密算法
- Discuz! Passport 采用 Azerbaijan Development Group(AzDG)開(kāi)發(fā)的可逆加密算法 AzDGCrypt 對(duì)用戶資料進(jìn)行加密。如提供正確的私有密匙,可通過(guò)本加密算法對(duì)數(shù)據(jù)進(jìn)行加密及解密,因此只要保證私有密匙的保密性,即可確保數(shù)據(jù)傳遞過(guò)程中的安全。以下為 Discuz! Passport 中應(yīng)用到的可逆加密算法,為了生成可以被 Discuz! Passport 正確解密的 auth 字串,需要將如下函數(shù)放置于應(yīng)用程序中,并可在登錄及注冊(cè)時(shí)調(diào)用。
- passport_encrypt()是加密函數(shù),用法為 passport_encrypt($txt, $key),其中 $txt 是待加密的字串,$key 是私有密匙。
- passport_decrypt()是解密函數(shù),用法為 passport_decrypt($txt, $key),其中 $txt 是加密后的字串,$key 是私有密匙。
/** * Passport 加密函數(shù) * * @param string 等待加密的原字串 * @param string 私有密匙(用于解密和加密) * * @return string 原字串經(jīng)過(guò)私有密匙加密后的結(jié)果 */ function passport_encrypt($txt, $key) { // 使用隨機(jī)數(shù)發(fā)生器產(chǎn)生 0~32000 的值并 MD5() srand((double)microtime() * 1000000); $encrypt_key = md5(rand(0, 32000)); // 變量初始化 $ctr = 0; $tmp = ''; // for 循環(huán),$i 為從 0 開(kāi)始,到小于 $txt 字串長(zhǎng)度的整數(shù) for($i = 0; $i < strlen($txt); $i++) { // 如果 $ctr = $encrypt_key 的長(zhǎng)度,則 $ctr 清零 $ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr; // $tmp 字串在末尾增加兩位,其第一位內(nèi)容為 $encrypt_key 的第 $ctr 位, // 第二位內(nèi)容為 $txt 的第 $i 位與 $encrypt_key 的 $ctr 位取異或。然后 $ctr = $ctr + 1 $tmp .= $encrypt_key[$ctr].($txt[$i] ^ $encrypt_key[$ctr++]); } // 返回結(jié)果,結(jié)果為 passport_key() 函數(shù)返回值的 base64 編碼結(jié)果 return base64_encode(passport_key($tmp, $key)); } /** * Passport 解密函數(shù) * * @param string 加密后的字串 * @param string 私有密匙(用于解密和加密) * * @return string 字串經(jīng)過(guò)私有密匙解密后的結(jié)果 */ function passport_decrypt($txt, $key) { // $txt 的結(jié)果為加密后的字串經(jīng)過(guò) base64 解碼,然后與私有密匙一起, // 經(jīng)過(guò) passport_key() 函數(shù)處理后的返回值 $txt = passport_key(base64_decode($txt), $key); // 變量初始化 $tmp = ''; // for 循環(huán),$i 為從 0 開(kāi)始,到小于 $txt 字串長(zhǎng)度的整數(shù) for ($i = 0; $i < strlen($txt); $i++) { // $tmp 字串在末尾增加一位,其內(nèi)容為 $txt 的第 $i 位, // 與 $txt 的第 $i + 1 位取異或。然后 $i = $i + 1 $tmp .= $txt[$i] ^ $txt[++$i]; } // 返回 $tmp 的值作為結(jié)果 return $tmp; } /** * Passport 密匙處理函數(shù) * * @param string 待加密或待解密的字串 * @param string 私有密匙(用于解密和加密) * * @return string 處理后的密匙 */ function passport_key($txt, $encrypt_key) { // 將 $encrypt_key 賦為 $encrypt_key 經(jīng) md5() 后的值 $encrypt_key = md5($encrypt_key); // 變量初始化 $ctr = 0; $tmp = ''; // for 循環(huán),$i 為從 0 開(kāi)始,到小于 $txt 字串長(zhǎng)度的整數(shù) for($i = 0; $i < strlen($txt); $i++) { // 如果 $ctr = $encrypt_key 的長(zhǎng)度,則 $ctr 清零 $ctr = $ctr == strlen($encrypt_key) ? 0 : $ctr; // $tmp 字串在末尾增加一位,其內(nèi)容為 $txt 的第 $i 位, // 與 $encrypt_key 的第 $ctr + 1 位取異或。然后 $ctr = $ctr + 1 $tmp .= $txt[$i] ^ $encrypt_key[$ctr++]; } // 返回 $tmp 的值作為結(jié)果 return $tmp; } /** * Passport 信息(數(shù)組)編碼函數(shù) * * @param array 待編碼的數(shù)組 * * @return string 數(shù)組經(jīng)編碼后的字串 */ function passport_encode($array) { // 數(shù)組變量初始化 $arrayenc = array(); // 遍歷數(shù)組 $array,其中 $key 為當(dāng)前元素的下標(biāo),$val 為其對(duì)應(yīng)的值 foreach($array as $key => $val) { // $arrayenc 數(shù)組增加一個(gè)元素,其內(nèi)容為 "$key=經(jīng)過(guò) urlencode() 后的 $val 值" $arrayenc[] = $key.'='.urlencode($val); } // 返回以 "&" 連接的 $arrayenc 的值(implode),例如 $arrayenc = array('aa', 'bb', 'cc', 'dd'), // 則 implode('&', $arrayenc) 后的結(jié)果為 ”aa&bb&cc&dd" return implode('&', $arrayenc); }
- passport_encode()是將數(shù)組轉(zhuǎn)換合成為字串形式存儲(chǔ)的函數(shù):變量名和數(shù)值之間用等號(hào)連接,如果數(shù)值包含特殊字符,使用 urlencode() 將其轉(zhuǎn)碼。多個(gè)變量間使用 & 分割。例如原始數(shù)組內(nèi)容為 array('username' => 'abc', 'email' => 'my+discuz@gmail.com'),經(jīng)過(guò) passport_encode() 編碼后結(jié)果為 username=abc&email=my%2Bdiscuz%40gmail.com。
信息字串(auth)
應(yīng)用程序在收到登錄或注冊(cè)請(qǐng)求,并讀取到用戶資料后,請(qǐng)按如下的要求將用戶資料及部分其他信息存放于一個(gè)數(shù)組之中。數(shù)組各鍵值的含義為:
- cookietime——應(yīng)用程序保存該用戶登錄記錄的時(shí)間,可為非負(fù)整數(shù),單位秒,Discuz! Passport 收到此參數(shù)后,會(huì)設(shè)置同樣的 Cookie 過(guò)期時(shí)間,這樣應(yīng)用程序和論壇可以保證同樣的登錄有效性。如不傳遞此參數(shù),或參數(shù)數(shù)值不正確,則 Discuz! Passport 按照 0 設(shè)置 Cookie 有效期。
- time——應(yīng)用程序所在服務(wù)器當(dāng)前時(shí)間(9 或 10 位數(shù)字 Unix Timestamp),此參數(shù)用于 Discuz! 所在服務(wù)器當(dāng)前時(shí)間進(jìn)行比對(duì),如果早于當(dāng)前時(shí)間超過(guò)若干秒(取決于 Discuz! Passport 中的“驗(yàn)證字串有效期”設(shè)定),則視為本 auth 內(nèi)容無(wú)效,避免此URL被人得知后可能的安全問(wèn)題。
- username——用戶登錄或注冊(cè)的用戶名。Discuz! 的注冊(cè)用戶名規(guī)則為:
- 長(zhǎng)度 1~15 個(gè)字符,不得為空
- 不得為 c:\con\con、游客(gb2312 或 big5 內(nèi)碼)、Guest
- 不得包含 (,)、(*)、(")、([TAB])、([SPACE])、([\r])、([\n])、(<)、(>)、(&)其中之一
- password——用戶密碼經(jīng) MD5 不可逆加密后的值。如果此密碼使用非 MD5 加密,則應(yīng)用程序和 Passport 不能正常關(guān)聯(lián)和使用。
- email——用戶 Email 地址(50 個(gè)字節(jié)以內(nèi))。
- isadmin——當(dāng)前用戶是否是應(yīng)用程序的最高管理員,1=是,0=否。最高管理員的權(quán)限,將同步到論壇中去,其他下級(jí)管理員的身份將不進(jìn)行同步,而由最高管理員分別在不同的系統(tǒng)中進(jìn)行設(shè)置。
- credits——當(dāng)前用戶在應(yīng)用程序中的積分值,范圍 -2147483648 到 2147483647,如果 Discuz! Passport 中設(shè)置了目標(biāo)積分項(xiàng),則用戶登錄時(shí),Passport 會(huì)把應(yīng)用程序傳遞過(guò)來(lái)的 credits 值同步到指定的論壇的指定積分項(xiàng)目中
- gender——當(dāng)前用戶的性別,1=男,2=女,0=未知。
- bday——當(dāng)前用戶的生日,格式 yyyy-mm-dd。
- regip——當(dāng)前用戶注冊(cè)時(shí)的 IP 地址。
- regdate——當(dāng)前用戶注冊(cè)的時(shí)間(9 或 10 位數(shù)字 Unix Timestamp)。
- nickname——當(dāng)前用戶的昵稱(30 個(gè)字節(jié)以內(nèi),如傳遞此參數(shù),必須打開(kāi)相應(yīng)用戶組的昵稱權(quán)限,否則用戶在控制面板中提交個(gè)人資料時(shí),會(huì)導(dǎo)致昵稱失效)。
- site——當(dāng)前用戶的主頁(yè)地址(包含http://)。
- qq——當(dāng)前用戶的 QQ 號(hào)碼。
- ICQ——當(dāng)前用戶的 ICQ 賬號(hào)。
- msn——當(dāng)前用戶的 MSN Messenger 賬號(hào)。
- yahoo——當(dāng)前用戶的 Yahoo! Messanger 賬號(hào)。
如果應(yīng)用程序提交過(guò)來(lái)的用戶名不符合上述規(guī)則,Passport 將自動(dòng)去處其中的特殊字符,將過(guò)濾后的結(jié)果寫入數(shù)據(jù)庫(kù)中。
以上參數(shù)中,以黑體下劃線顯示的 time、username、password、email 是必須傳遞的參數(shù),缺少上述參數(shù) Passport 將無(wú)法正常工作。其他的參數(shù)是可選的,如果不傳遞某些參數(shù),則 Passport 會(huì)進(jìn)行識(shí)別,自動(dòng)不更新沒(méi)有傳遞的參數(shù)所在的字段。所有數(shù)值,請(qǐng)?zhí)峁┰贾?,而非?jīng)過(guò)反斜線轉(zhuǎn)義(addslashes)后的結(jié)果。
把上述信息存放于數(shù)組中,假定為如下的形式:
$member = array ( 'cookietime' => 31536000, 'time' => 1117415922, 'username' => 'Abcd', 'password' => 'e2fc714c4727ee9395f324cd2e7f331f', 'email' => 'abcd@efgh.com', 'credits' => 123, 'regip' => '210.120.222.111', 'regdate' => '1012752000', 'msn' => 'email@hotmail.com' );
將其經(jīng)過(guò)如下的加密變換,即可得到 auth 的值:
$auth = passport_encrypt(passport_encode($member), $passport_key);
其中,passport_encode() 在前文已做了說(shuō)明,用于將數(shù)組內(nèi)容存放于特定的格式,$passport_key 是私有密匙。
切記:由于 $auth 中可能含有等號(hào)、加號(hào)等特殊字符,請(qǐng)將 $auth 經(jīng)過(guò) rawurlencode() 編碼后再在 URL 中傳遞,否則可能會(huì)產(chǎn)生問(wèn)題。
導(dǎo)向字串(forward)
導(dǎo)向字串用于通知 Discuz! Passport 在完成自身操作后,返回到哪一個(gè) URL 地址,例如 http://www.myforums.com/forumdisplay.php?fid=2。如果 forward 為空,則默認(rèn)導(dǎo)向到應(yīng)用程序的首頁(yè)
切記:由于 $forward 中可能含有冒號(hào)、問(wèn)號(hào)、等號(hào)等特殊字符,請(qǐng)將 $forward 經(jīng)過(guò) rawurlencode() 編碼后再在 URL 中傳遞,否則可能會(huì)產(chǎn)生問(wèn)題。
驗(yàn)證字串(verify)
驗(yàn)證字串用戶檢驗(yàn) auth 和 forward 兩個(gè)參數(shù)的合法性,避免非法構(gòu)造參數(shù)進(jìn)行破壞的可能。無(wú)論 auth 和 forward 變量是否存在,驗(yàn)證字串(verify)的值均為:
$verify = md5($action.$auth.$forward.$passport_key);
其中,$action 是當(dāng)前執(zhí)行的 Passport 操作,如 login 等等;$auth 是用戶信息加密后,并經(jīng) rawurlencode() 之前的內(nèi)容。$forward 是經(jīng) rawurlencode() 前的導(dǎo)向字串、$passport_key 是私有密匙。如果 verify 的值不匹配,則 Passport 拒絕進(jìn)行下一步操作。
Discuz! Passport 設(shè)置與啟用
內(nèi)置關(guān)聯(lián)
Discuz! 以戰(zhàn)略合作的方式,與業(yè)內(nèi)知名的產(chǎn)品實(shí)現(xiàn)了 Passport 關(guān)聯(lián),目前內(nèi)置了 SiteEngine 建站引擎(http://www.siteengine.net)和 Shopex 通用型網(wǎng)上商店系統(tǒng)(http://www.shopex.cn)的相關(guān)接口,這樣用戶只須透過(guò)在兩套軟件中簡(jiǎn)單的設(shè)置,即可開(kāi)啟這些關(guān)聯(lián)。
其他應(yīng)用程序
由于 Discuz! Passport 的高可擴(kuò)展性和平臺(tái)無(wú)關(guān)性,使得您可以參照前文的說(shuō)明,稍稍改動(dòng)小部分的代碼,便將任何 B/S 模式的應(yīng)用程序與 Discuz! 進(jìn)行關(guān)聯(lián)。
參數(shù)設(shè)置
您可以在 Discuz! 系統(tǒng)設(shè)置中,看到相應(yīng)的通行證設(shè)置功能,在 Discuz! 合作伙伴的軟件中,也可以找到這些設(shè)置入口。相關(guān)的操作已比較簡(jiǎn)單,在此不再詳細(xì)敘述。
特別說(shuō)明
如果您先運(yùn)營(yíng)了論壇,后與其他應(yīng)用程序啟用了 Passport 關(guān)聯(lián),由于之前論壇中的用戶數(shù)據(jù)沒(méi)有同步,您需要先寫一個(gè)導(dǎo)入程序,將論壇的用戶數(shù)據(jù)導(dǎo)入到應(yīng)用程序的用戶表中,否則以往在論壇注冊(cè)的用戶將無(wú)法通過(guò) Passport 登錄。已成功關(guān)聯(lián)后新注冊(cè)的用戶無(wú)此問(wèn)題。
在開(kāi)啟了 Discuz! 通行證后,您仍然可以通過(guò) logging.php?action=login 這個(gè)鏈接來(lái)登錄論壇,以備調(diào)試之用,但頁(yè)面上顯示的鏈接將改為應(yīng)用程序的登錄 URL。注意:開(kāi)啟通行證后,建議您通過(guò) Discuz! 選項(xiàng)關(guān)閉論壇本身的注冊(cè)功能,以免用戶通過(guò)論壇注冊(cè)而產(chǎn)生無(wú)法同步的問(wèn)題。
您可以在 Discuz! 的 api/passport.php 找到 Discuz! Passport 的全部源程序,您也許通過(guò)他更好的理解 Passport 的原理,更快的完成應(yīng)用程序與 Discuz! 之間的整合。
典型錯(cuò)誤提示
Illegal request
非法請(qǐng)求,當(dāng)驗(yàn)證字串 verify 不匹配時(shí)會(huì)產(chǎn)生此提示。可能是應(yīng)用程序與 Discuz! 配置的私有密匙不同,或是通過(guò) URL 傳遞前,未將必要的參數(shù)(如 auth、forward 等)進(jìn)行 URL 編碼,也有可能是使用了經(jīng)過(guò) URL 編碼的參數(shù)值用來(lái)計(jì)算 verify 的 md5 值造成。以 PHP 語(yǔ)言為例,正確的代碼應(yīng)當(dāng)是類似于的如下的格式:
$action = 'login'; $auth = passport_encrypt(passport_encode($autharray), $passport_key); $forward = 'http://www.discuz.net/index.php'; $verify = md5($action.$auth.$forward.$passport_key); header("Location: http://www.discuz.net/api/passport.php". "?action=$action". "&auth=".rawurlencode($auth). "&forward=".rawurlencode($forward). "&verify=$verify");
Lack of required parameters
auth 內(nèi)容解密后,缺少必要的信息 time、username、password、email。
Request expired
請(qǐng)求過(guò)期。當(dāng)前服務(wù)器時(shí)間與應(yīng)用程序提交過(guò)來(lái)的 time 之差大于 Discuz! Passport 中設(shè)置的請(qǐng)求有效期??赡苁鞘褂靡酝拇a非法嘗試,也可能是由于應(yīng)用程序和 Discuz! 論壇所在的兩臺(tái)服務(wù)器,時(shí)間設(shè)置有誤造成。
Invalid action
沒(méi)有指定 Passport 所執(zhí)行的 action。