跨站(跨域)單點(diǎn)登錄的實(shí)現(xiàn)(SSO)

本文分兩部分

1.轉(zhuǎn)他人的文章肯腕,詳細(xì)介紹了跨站單點(diǎn)登錄的原理和解決方案

2.我自己寫(xiě)代碼,著重介紹里面的重點(diǎn)部分

1:

假設(shè)我們需要在以下這些站之間實(shí)現(xiàn)單點(diǎn)登錄

www.onmpw1.com

www.onmpw2.com

www.onmpw3.com

對(duì)于這種情況堡僻,我們有兩種實(shí)現(xiàn)方式糠惫,其中我們先來(lái)介紹實(shí)現(xiàn)比較簡(jiǎn)單的方式。

方式一

為了實(shí)現(xiàn)單點(diǎn)登錄钉疫,當(dāng)用戶(hù)登錄其中的任何一個(gè)站點(diǎn)時(shí)硼讽,我們需要針對(duì)其他每個(gè)站點(diǎn)在瀏覽器端設(shè)置cookie信息。

如果用戶(hù)在onmpw1站點(diǎn)進(jìn)行登錄牲阁,登錄成功授權(quán)以后固阁,瀏覽器將會(huì)存儲(chǔ)一份兒onmpw1站點(diǎn)的cookie信息壤躲。同時(shí),為了可以登錄onmpw2和onmpw3备燃,我們需要在設(shè)置onmpw1的cookie的同事也對(duì)onmpw2和onmpw3進(jìn)行cookie設(shè)置碉克。因此在對(duì)onmpw1進(jìn)行響應(yīng)之前,我們需要先跳轉(zhuǎn)到onmpw2和onmpw3站點(diǎn)去設(shè)置cookie信息并齐。

下圖是對(duì)于兩個(gè)站點(diǎn)的單點(diǎn)登錄模型(三個(gè)的圖畫(huà)起來(lái)比較麻煩漏麦,為了節(jié)省時(shí)間,就用兩個(gè)來(lái)表示冀膝,但是原理是相同的)

此種情況的驗(yàn)證步驟是這樣的:

一唁奢、用戶(hù)向www.onmpw1.com(以下簡(jiǎn)稱(chēng)onmpw1)請(qǐng)求一個(gè)需要驗(yàn)證的頁(yè)面。

[狀態(tài): 瀏覽器還沒(méi)有驗(yàn)證的cookie信息]

二窝剖、瀏覽器向onmpw1發(fā)送請(qǐng)求(該請(qǐng)求沒(méi)有cookie信息麻掸,因?yàn)樗€沒(méi)有存儲(chǔ)所屬域?yàn)閛nmpw1.com的cookie信息)。

[狀態(tài): 瀏覽器還沒(méi)有驗(yàn)證的cookie信息]

三赐纱、onmpw1發(fā)現(xiàn)在請(qǐng)求中沒(méi)有帶cookie信息脊奋,所以它將請(qǐng)求重定向到登錄頁(yè)面

[狀態(tài): 瀏覽器還沒(méi)有驗(yàn)證的cookie信息]

四、用戶(hù)提交了登錄所需驗(yàn)證的信息并且點(diǎn)擊登錄按鈕疙描,瀏覽器發(fā)送一個(gè)post請(qǐng)求到onmpw1诚隙。

[狀態(tài): 瀏覽器還沒(méi)有驗(yàn)證的cookie信息]

五、onmpw1收到提交的驗(yàn)證信息起胰,開(kāi)始驗(yàn)證這些信息淮菠。如果驗(yàn)證成功涯穷,則標(biāo)記該用戶(hù)已經(jīng)登錄。然后會(huì)創(chuàng)建帶有登錄用戶(hù)信息的cookie,并將其加入響應(yīng)信息中速梗。

[狀態(tài): 瀏覽器還沒(méi)有驗(yàn)證的cookie信息]

六徽龟、onmpw1暫時(shí)還不去響應(yīng)瀏覽器的請(qǐng)求绩聘。這時(shí)它將會(huì)向?yàn)g覽器發(fā)送重定向到www.onmpw2.com(以下簡(jiǎn)稱(chēng)onmpw2)的命令踢代,并且還帶有在onmpw2站點(diǎn)需要返回的url地址,該地址為最初onmpw1中的戒劫。因?yàn)閏ookie信息已經(jīng)在響應(yīng)信息中半夷,所以這個(gè)cookie也被發(fā)送給瀏覽器了。

[狀態(tài): 瀏覽器還沒(méi)有驗(yàn)證的cookie信息]

七迅细、瀏覽器接收道帶有驗(yàn)證的cookie信息和重定向到onmpw2的命令的響應(yīng)信息以后巫橄,將cookie信息的域設(shè)置為onmpw2存儲(chǔ)到本地,并且想onmpw2發(fā)送請(qǐng)求茵典。這個(gè)請(qǐng)求中會(huì)帶有剛才的cookie信息嗦随。

[狀態(tài):瀏覽器中已經(jīng)有所屬域?yàn)閛nmpw2的cookie信息]

八、onmpw2立刻會(huì)重定向到需要返回的url地址,并且通過(guò)讀取瀏覽器發(fā)送的cookie信息枚尼,獲取到onmpw1的cookie贴浙。并將這cookie也一同發(fā)送給瀏覽器。

[狀態(tài):瀏覽器中已經(jīng)有所屬域?yàn)閛nmpw2的cookie信息]

九署恍、瀏覽器在接受到這些信息以后崎溃,會(huì)將所屬域?yàn)閛nmpw1的cookie存儲(chǔ)在本地。并且再次向onmpw1發(fā)送一個(gè)帶有cookie信息的請(qǐng)求盯质。

[狀態(tài):瀏覽器中已經(jīng)有所屬域?yàn)閛nmpw2和onmpw1的cookie信息]

十袁串、onmpw1接收到驗(yàn)證信息以后,知道驗(yàn)證cookie已經(jīng)設(shè)置成功呼巷。此時(shí)onmpw1會(huì)返回相應(yīng)的請(qǐng)求界面囱修,而不再是登錄界面。

[狀態(tài):瀏覽器中已經(jīng)有所屬域?yàn)閛nmpw2和onmpw1的cookie信息]

所以說(shuō)王悍,當(dāng)用戶(hù)再次訪問(wèn)onmpw2的時(shí)候破镰,cookie信息已經(jīng)存儲(chǔ)到瀏覽器中了。這時(shí)onmpw2會(huì)在cookie中讀取到登錄的用戶(hù)的信息压储,然后提供相應(yīng)的界面給瀏覽器鲜漩。

這樣,單點(diǎn)登錄就已經(jīng)設(shè)置成功了集惋。在本例中孕似,按照上述步驟,登錄onmpw1以后刮刑,onmpw2和onmpw3就可以同時(shí)實(shí)現(xiàn)登錄了喉祭。

如何退出登錄

既然我們已經(jīng)實(shí)現(xiàn)了單點(diǎn)登錄,但是我們還得考慮退出的問(wèn)題雷绢。既然是同時(shí)登錄的泛烙,那總不能在退出的時(shí)候一個(gè)一個(gè)的退出吧!所以說(shuō)我們還要設(shè)置單點(diǎn)退出习寸。

要想實(shí)現(xiàn)單點(diǎn)退出,在本例中傻工,我們需要做的是當(dāng)在一個(gè)站點(diǎn)退出的時(shí)候霞溪,其他兩個(gè)站點(diǎn)的cookie同樣也需要在瀏覽器中清除。這樣才可以實(shí)現(xiàn)單點(diǎn)退出中捆。

這樣其實(shí)也很簡(jiǎn)單鸯匹,在理解了上述單點(diǎn)登錄的流程以后,單點(diǎn)退出只是按照上面的步驟將設(shè)置驗(yàn)證cookie改成從響應(yīng)信息中移除cookie就可以實(shí)現(xiàn)了泄伪。

對(duì)于這種情況殴蓬,不管是單點(diǎn)登錄也好,還是單點(diǎn)退出。都存在一個(gè)問(wèn)題染厅,在本例中我們只是有三個(gè)站點(diǎn)痘绎。如果說(shuō)我們整個(gè)系統(tǒng)有10個(gè)20個(gè)或者更多站點(diǎn),那像我們這樣來(lái)回的重定向會(huì)很影響效率肖粮。

方式二

接下來(lái)我們來(lái)介紹另一種方式孤页。這種方式需要我們借助一個(gè)單獨(dú)的SSO服務(wù),專(zhuān)門(mén)做驗(yàn)證用涩馆。而且我們還需要對(duì)于不同的站點(diǎn)的用戶(hù)要有一個(gè)統(tǒng)一的用戶(hù)數(shù)據(jù)行施。相對(duì)于前一種方式——瀏覽器需要存儲(chǔ)每個(gè)站點(diǎn)的cookie——來(lái)說(shuō),這種方式瀏覽器只需要存儲(chǔ)SSO服務(wù)站點(diǎn)的cookie信息魂那。將這個(gè)cookie信息用于其他站點(diǎn)從而實(shí)現(xiàn)單點(diǎn)登錄蛾号。我們暫且將這個(gè)SSO服務(wù)站點(diǎn)成為www.SSOsite.com(以下簡(jiǎn)稱(chēng)SSOsite)。

在這種模型下涯雅,針對(duì)任何站點(diǎn)的請(qǐng)求都將會(huì)先重定向到SSOsite去驗(yàn)證一個(gè)身份驗(yàn)證cookie是否存在鲜结。如果存在,則驗(yàn)證過(guò)的頁(yè)面將會(huì)發(fā)送給瀏覽器斩芭。否則用戶(hù)將會(huì)被重定向到登錄頁(yè)面轻腺。

為了理解此種方式,現(xiàn)在假設(shè)我們來(lái)運(yùn)用這種模型實(shí)現(xiàn)以下兩個(gè)站點(diǎn)的單點(diǎn)登錄划乖。

www.onmpw1.com(以下簡(jiǎn)稱(chēng)onmpw1)

www.onmpw2.com(以下簡(jiǎn)稱(chēng)onmpw2)

并且我們還有一個(gè)專(zhuān)門(mén)用來(lái)進(jìn)行驗(yàn)證的服務(wù)站點(diǎn)www.SSOsite.com(以下簡(jiǎn)稱(chēng)SSOsite) 贬养。

第一部分

實(shí)現(xiàn)流程

·用戶(hù)請(qǐng)求onmpw1的一個(gè)需要驗(yàn)證的頁(yè)面

·onmpw1向?yàn)g覽器發(fā)送重定向到SSOsite的命令。并且在地址中添加一個(gè)返回地址(ReturnUrl)參數(shù)query string琴庵,該參數(shù)的值就是最初向onmpw1請(qǐng)求的地址误算。

·SSOsite會(huì)在請(qǐng)求中檢查是否有身份驗(yàn)證cookie,或者任何用戶(hù)token迷殿。沒(méi)有這些信息儿礼,則會(huì)再次重定向到onmpw1,在重定向到onmpw1中的請(qǐng)求中會(huì)帶有參數(shù)讓用戶(hù)登錄的url參數(shù)和最初的瀏覽器請(qǐng)求onmpw1的地址——ReturnUrl庆寺。

·onmpw1會(huì)檢測(cè)從SSOsite重定向來(lái)的請(qǐng)求的參數(shù)蚊夫。這時(shí)onmpw1了解到該用戶(hù)需要登錄,因此onmpw1會(huì)重定向到登錄界面懦尝,并且通知瀏覽器該請(qǐng)求不用再重定向到SSOsite知纷。

第二部分

·用戶(hù)提供了身份驗(yàn)證信息并且點(diǎn)擊了登錄按鈕。現(xiàn)在不會(huì)再去重定向到SSOsite陵霉。這時(shí)琅轧,onmpw1調(diào)用SSOsite 中的web/WCF服務(wù)去檢查用戶(hù)提供的身份驗(yàn)證信息。成功驗(yàn)證踊挠,會(huì)將帶有token屬性的用戶(hù)對(duì)象返回給onmpw1乍桂。而這個(gè)token是每一次用戶(hù)登錄都會(huì)生成的。

·onmpw1標(biāo)記用戶(hù)已經(jīng)登錄成功,然后會(huì)生成一個(gè)URL地址睹酌,該地址會(huì)帶有用戶(hù)token权谁,重定向到SSOsite。

·SSOsite檢查收到的URL地址忍疾,會(huì)在其中發(fā)現(xiàn)用戶(hù)token闯传。通過(guò)該token可以知道用戶(hù)已經(jīng)成功登錄onmpw1了,所以SSOsite需要準(zhǔn)備驗(yàn)證的cookie信息卤妒。因此甥绿,它會(huì)使用token在緩存中取出用戶(hù)信息來(lái)生成cookie信息,而且還會(huì)在cookie中設(shè)置一些其他的信息(例如過(guò)期時(shí)間等)则披。然后把cookie加入到響應(yīng)信息中共缕。最后重定向到最初的ReturnUrl地址。同時(shí)token還是要被加在query string中帶過(guò)去的士复。

·瀏覽器得到重定向到onmpw1的命令图谷,并且從SSOsite中得到cookie信息。因此瀏覽器將所屬域?yàn)镾SOsite的cookie保存在本地阱洪。然后帶著token去請(qǐng)求onmpw1便贵。

·現(xiàn)在onmpw1看到用戶(hù)token在query string 參數(shù)中,然后會(huì)再次通過(guò)web/WCF服務(wù)去在SSOsite上驗(yàn)證token冗荸。驗(yàn)證成功以后會(huì)將最初剛開(kāi)始請(qǐng)求的頁(yè)面發(fā)送給瀏覽器用于向用戶(hù)輸出承璃。

第三部分

·用戶(hù)現(xiàn)在去請(qǐng)求onmpw2。

·onmpw2重定向到SSOsite蚌本,同樣設(shè)置ReturnUrl為剛開(kāi)始請(qǐng)求的onmpw2的頁(yè)面地址盔粹。

·瀏覽器接收到重定向的命令以后,因?yàn)楸镜卮嬖赟SOsite的cookie程癌,所以會(huì)cookie加到請(qǐng)求中發(fā)送給SSOsite舷嗡。

·SSOsite檢查接收到的請(qǐng)求中發(fā)現(xiàn)有cookie信息,首先會(huì)檢查該cookie信息是否過(guò)期嵌莉,如果沒(méi)有過(guò)期进萄,將會(huì)從cookie中提取出用戶(hù)token。然后帶著token重定向到最初的onmpw2中的地址锐峭。

·onmpw2發(fā)現(xiàn)請(qǐng)求中有用戶(hù)token中鼠,然后他會(huì)通過(guò)SSOsite的web/WCF服務(wù)驗(yàn)證token的合法性。驗(yàn)證成功以后只祠,將最初瀏覽器請(qǐng)求onmpw2的頁(yè)面發(fā)送給瀏覽器用以向用戶(hù)輸出兜蠕。

總結(jié)

哇哦扰肌,看起來(lái)有很多東西需要做抛寝。其實(shí)并沒(méi)有那么復(fù)雜。

起初,瀏覽器沒(méi)有所屬域?yàn)镾SOsite的cookie信息盗舰。因此無(wú)論是點(diǎn)擊任何站點(diǎn)的需要驗(yàn)證的界面都會(huì)跳轉(zhuǎn)到登錄頁(yè)(這個(gè)過(guò)程是由程序內(nèi)部重定向到SSOsite來(lái)檢查是否存在cookie的)晶府。一旦用戶(hù)登錄成功,所屬域?yàn)镾SOsite的钻趋,并且?guī)в械卿浻脩?hù)信息的cookie會(huì)被瀏覽器存儲(chǔ)在本地川陆。

然后,當(dāng)用戶(hù)再次訪問(wèn)需要驗(yàn)證的頁(yè)面的時(shí)候蛮位,同樣請(qǐng)求會(huì)在被重定向到SSOsite较沪,并且瀏覽器會(huì)帶上先前已經(jīng)保存的cookie信息。SSOsite檢索cookie失仁,從中提取出用戶(hù)token尸曼,并帶著這個(gè)token重定向到最初請(qǐng)求的站點(diǎn)頁(yè)面。然后該站點(diǎn)會(huì)通過(guò)web/WCF服務(wù)去驗(yàn)證token的合法性萄焦。然后將相應(yīng)的頁(yè)面發(fā)送給客戶(hù)端控轿。

一旦用戶(hù)通過(guò)該單點(diǎn)登錄模型登錄到站點(diǎn)上,請(qǐng)求任何需要驗(yàn)證的頁(yè)面都會(huì)內(nèi)部重定向到SSOsite驗(yàn)證cookie和提取用戶(hù)token拂封,然后將請(qǐng)求的頁(yè)面發(fā)送給瀏覽器輸出茬射。

2:

上面的兩個(gè)方案,重點(diǎn)都是帶著參數(shù)(可能是URL冒签,可能是token)重定向到另一個(gè)域名下在抛,

去請(qǐng)求這個(gè)域名下的應(yīng)用程序,然后應(yīng)用程序在新域名下生成COOKIE或者token镣衡,

然后再帶著Token(方案一之生成COOKIE霜定,不帶TOKEN)重定向回去。

下面我用PHP代碼模擬下

www.a.com????這個(gè)域名下有文件login.php 內(nèi)容如下

if(!array_key_exists('jump',$_GET)){setcookie("login",1);header('Location: http://www.b.com/login.php?jump');}

(圖1)

www.b.com????這個(gè)域名下也有個(gè)程序文件index.php(其實(shí)名字隨意)?內(nèi)容如下

if(array_key_exists('jump',$_GET)){setcookie("login",1);header('Location: http://www.a.com/login.php?jump');}

(圖2)

一開(kāi)始廊鸥,用戶(hù)在這兩個(gè)域名下望浩,未登錄的話都是沒(méi)COOKIE的。

此時(shí)用戶(hù)先訪問(wèn) a域名的login.php,登錄a成功之后執(zhí)行上面圖1的代碼惰说,

由于直接訪問(wèn)的www.a.com/login.php,

并沒(méi)有jump這個(gè)參數(shù)(圖2說(shuō)這個(gè)參數(shù)的作用)磨德,所以設(shè)置login成功,并用header重定向到了www.b.com/login且?guī)е鴍ump參數(shù)

當(dāng)b下的login.php收到j(luò)ump過(guò)來(lái)的參數(shù)時(shí)吆视,說(shuō)明是a登錄成功過(guò)來(lái)的典挑,那么b下的程序就直接設(shè)置cookie為 login=1

(此時(shí)因?yàn)橐呀?jīng)到了b域名下執(zhí)行的應(yīng)用程序,所以COOKIE的有效域?yàn)?a target="_blank" rel="nofollow">www.b.com)

之后再由b再重定向到 a域名啦吧,帶著jump參數(shù)您觉,這樣a就不會(huì)再跳轉(zhuǎn)到b下了。

此時(shí)授滓,www.a.comwww.b.com這兩個(gè)域名下琳水,都有了登錄狀態(tài)的cookie肆糕。

用戶(hù)無(wú)論去那個(gè)站,都不用再登錄了在孝。

方式一的原理即以上

方式二略

這兩個(gè)的重點(diǎn)诚啃,都是重定向到新域名之后生成新域名的cookie,然后再重定向回來(lái)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末私沮,一起剝皮案震驚了整個(gè)濱河市始赎,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌仔燕,老刑警劉巖造垛,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異晰搀,居然都是意外死亡筋搏,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)厕隧,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)奔脐,“玉大人,你說(shuō)我怎么就攤上這事吁讨∷栌” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵建丧,是天一觀的道長(zhǎng)排龄。 經(jīng)常有香客問(wèn)我,道長(zhǎng)翎朱,這世上最難降的妖魔是什么橄维? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮拴曲,結(jié)果婚禮上争舞,老公的妹妹穿的比我還像新娘。我一直安慰自己澈灼,他們只是感情好竞川,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布。 她就那樣靜靜地躺著叁熔,像睡著了一般委乌。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上荣回,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天遭贸,我揣著相機(jī)與錄音,去河邊找鬼心软。 笑死壕吹,一個(gè)胖子當(dāng)著我的面吹牛除秀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播算利,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼泳姐!你這毒婦竟也來(lái)了效拭?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤胖秒,失蹤者是張志新(化名)和其女友劉穎缎患,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體阎肝,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡挤渔,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了风题。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片判导。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖沛硅,靈堂內(nèi)的尸體忽然破棺而出眼刃,到底是詐尸還是另有隱情,我是刑警寧澤摇肌,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布擂红,位于F島的核電站,受9級(jí)特大地震影響围小,放射性物質(zhì)發(fā)生泄漏昵骤。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一肯适、第九天 我趴在偏房一處隱蔽的房頂上張望变秦。 院中可真熱鬧,春花似錦框舔、人聲如沸伴栓。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)钳垮。三九已至,卻和暖如春额港,著一層夾襖步出監(jiān)牢的瞬間饺窿,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工移斩, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留肚医,地道東北人绢馍。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像肠套,于是被迫代替她去往敵國(guó)和親舰涌。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容