在跨域場景下實(shí)現(xiàn)單點(diǎn)登錄和網(wǎng)站內(nèi)容融合

前言

在企業(yè)業(yè)務(wù)發(fā)生變化時(shí),采用技術(shù)手段整合多個(gè)網(wǎng)站從來就不是一件輕松的事情绍傲。這里面的障礙主要有:

  1. 不同的賬號和權(quán)限管理體系
  2. 不同的界面風(fēng)格
  3. 生硬的鏈接跳轉(zhuǎn)
  4. 難以復(fù)用的后端接口

從我們的經(jīng)驗(yàn)看幻枉,以上問題要解決碰声,需要使用一種漸進(jìn)整合的架構(gòu),因?yàn)檎吓f內(nèi)容和生產(chǎn)新內(nèi)容是同時(shí)進(jìn)行的熬甫,我們做的事情就像是:開著飛機(jī)換引擎胰挑。

解決思路

本文介紹一種在跨域場景下實(shí)現(xiàn)單點(diǎn)登錄和網(wǎng)站內(nèi)容融合的方案,針對性解決前述 4 大障礙,其對應(yīng)的主要技術(shù)點(diǎn)是:

  1. 通過單點(diǎn)登錄統(tǒng)一賬號
  2. 通過 iframe 門戶頁提供統(tǒng)一的外框?qū)Ш讲藛?/li>
  3. 通過攔截鏈接跳轉(zhuǎn)和重置地址欄瞻颂,實(shí)現(xiàn)統(tǒng)一的鏈接跳轉(zhuǎn)行為
  4. 通過支持 CORS 請求協(xié)議豺谈,接口可以部署在任何一個(gè)關(guān)聯(lián)應(yīng)用

以下舉例說明此方案。

假設(shè)我們需要整合的網(wǎng)站分別是 a.my.com(簡稱 a )和 b.my.com(簡稱 b ) 贡这。

實(shí)現(xiàn)單點(diǎn)登錄

為了實(shí)現(xiàn)單點(diǎn)登錄茬末,我們需要新增單點(diǎn)登錄服務(wù)器 sso.my.com

改造 a盖矫、b 網(wǎng)站底層丽惭,讓他們的用戶賬號映射為一個(gè)統(tǒng)一的 uniqueId 。并在底層調(diào)用單點(diǎn)登錄服務(wù)器提供的登錄認(rèn)證辈双。

用戶首次訪問 a 網(wǎng)站感知到的流程如下:

  1. 用戶訪問頁面 //a.my.com/page.htm
  2. a.my.com 調(diào)用 sso.my.com 認(rèn)證服務(wù)進(jìn)行鑒權(quán)
  3. 鑒權(quán)失敗责掏,跳轉(zhuǎn)登錄頁 //sso.my.com/login.htm?returnUrl=//a.my.com/page.htm
  4. 登錄后回跳進(jìn)入頁面 //a.my.com/page.htm

同理,用戶首次訪問 b 網(wǎng)站辐马,也會獲得一致的體驗(yàn)拷橘。

下面是一個(gè)淘寶的單點(diǎn)登錄的案例,訪問"我的淘寶"頁面喜爷,進(jìn)入的是登錄頁冗疮。

原頁面地址:https://i.taobao.com/my_taobao.htm

帶回跳的登錄頁地址:https://login.taobao.com/member/login.jhtml?redirect_url=https%3A%2F%2Fi.taobao.com%2Fmy_taobao.htm(如圖 1 所示)

圖 1. 帶回跳的淘寶登錄頁地址
image.png

構(gòu)建 iframe 門戶頁

iframe 框架曾經(jīng)是早期網(wǎng)站內(nèi)容布局的一種方式,后來因?yàn)?Ajax 能自由地進(jìn)行局部刷新檩帐,iframe 的必要性下降术幔,加上開發(fā)維護(hù)的成本較高,逐漸被減少使用湃密,僅在部分場景使用诅挑。但本文正是充分利用 iframe 的特點(diǎn):能隔離外框?qū)Ш讲藛魏晚撁鎯?nèi)容。

為了實(shí)現(xiàn) iframe 門戶頁泛源,我們需要新增門戶服務(wù)器 portal.my.com拔妥。

開發(fā)一個(gè) iframe 門戶頁 portal.my.com/home.htm,以后所有的頁面請求达箍,都通過它嵌套訪問没龙。

改造 a、b 網(wǎng)站頁面的腳手架缎玫,讓頁面擁有兩種模式:獨(dú)立使用模式和嵌套使用模式硬纤,在嵌套使用模式下隱藏原有的菜單信息。

用戶訪問 a 網(wǎng)站感知到的流程如下:

  1. 用戶訪問頁面 //portal.my.com/home.htm?page=//a.my.com/page.htm
  2. iframe 門戶頁根據(jù)參數(shù)呈現(xiàn)外框?qū)Ш讲藛?/li>
  3. iframe 門戶頁中的 iframe赃磨,間接訪問 //a.my.com/page.htm?mode=nested 筝家,呈現(xiàn)頁面內(nèi)容。在這個(gè)例子中邻辉,模式 (mode)參數(shù)值 nested 表示頁面以嵌套的方式被訪問溪王,指示不要渲染頁面原有的菜單(如有)

同理腮鞍,用戶首次訪問 b 網(wǎng)站,也會獲得一致的體驗(yàn)在扰。

為了獲得更好的體驗(yàn)缕减,應(yīng)該更改原有頁面的主題,讓他們的主題顏色等樣式趨于一致芒珠,如圖 2 所示:

圖 2. 更改原有頁面的主題
image.png

攔截鏈接跳轉(zhuǎn)和重置地址欄

現(xiàn)在用戶直接通過頁面地址打開頁面桥狡,已經(jīng)能獲得我們所期望的頁面效果。但是頁面上的鏈接發(fā)生點(diǎn)擊時(shí)皱卓,會發(fā)生以下兩種情況:

  1. 在 iframe 中跳轉(zhuǎn)
  2. 在新窗口或新標(biāo)簽頁打開頁面

需要注意的是裹芝,頁面上原有的跳轉(zhuǎn)代碼目前還沒有去重構(gòu),所以跳轉(zhuǎn)地址仍然是直接地址娜汁,而不是形如 //portal.my.com/home.htm?page=//a.my.com/page.htm 這樣的封裝地址嫂易。 <a> 標(biāo)簽可以攔截點(diǎn)擊事件,代碼中的跳轉(zhuǎn)則只能重構(gòu)代碼掐禁,比如調(diào)用一個(gè)新的公共鏈接跳轉(zhuǎn)方法怜械。

我們可以制作一個(gè)公共的 JS 文件,并改造原有頁面傅事,引入這個(gè) JS 文件以便攔截跳轉(zhuǎn)缕允。在攔截到跳轉(zhuǎn)后:

  1. 針對情況 1,通過 history.pushState 重置地址欄蹭越,讓地址欄顯示新的封裝地址障本。
  2. 針對情況 2,在新窗口或新標(biāo)簽頁按照新的封裝地址打開頁面响鹃。

為了獲得更好的體驗(yàn)驾霜,我們還可以進(jìn)行 URL 重寫,讓用戶通過 REST 風(fēng)格的 URL 進(jìn)行訪問买置,這時(shí) URL 的格式是: //portal.my.com/home/page/a.my.com/page 粪糙。

圖 3. 攔截鏈接跳轉(zhuǎn)
image.png

改造后端接口

將后端接口改造為支持 CORS 請求的后端接口,這樣跨域訪問接口不再成為障礙忿项,接口可以部署到任意關(guān)聯(lián)應(yīng)用中猜旬。

圖 4 是 CORS 示意圖 (來源:https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS)。與頁面不在一個(gè)域的請求倦卖,即為 CORS 請求。

圖 4. CORS 示意圖
image.png

對一個(gè)簡單的請求椿争,沒有自定義頭部怕膛,要么使用 GET,要么使用 POST秦踪,它的 Content-Type 請求頭是 text/plain褐捻、multipart/form-data 或者 application/x-www-form-urlencoded 掸茅,瀏覽器會自動添加一個(gè)名叫 Origin 的額外的頭部發(fā)送 請求 。Origin 頭部包含請求頁面的協(xié)議域名柠逞、端口昧狮,這樣服務(wù)器可以很容易的決定它是否應(yīng)該提供響應(yīng)。服務(wù)器端對于 CORS 的支持板壮,主要就是通過設(shè)置 Access-Control-Allow-Origin 響應(yīng)頭來進(jìn)行的逗鸣。

瀏覽器發(fā)出的請求如清單 1 所示:

清單 1. 瀏覽器發(fā)出的請求
GET /api HTTP/1.1
…
HOST: api.my.com
Referer: http://portal.my.com/home.htm?page=//a.my.com/page.htm
Origin: http://portal.my.com

一個(gè)支持 CORS 的服務(wù)可能給出如清單 2 響應(yīng):
清單 2. 一個(gè)支持 CORS 的服務(wù)響應(yīng)

HTTP/1.1 200 OK
Access-Control-Allow-Origin: http://portal.my.com
Content-Type: application/json; charset=UTF8
…
 
[Payload Here]

通常,如果在使用 Fetch 發(fā)送請求時(shí)绰精,如果需要攜帶 cookie撒璧,還需指定 credentials 為 include,如圖 5 所示

圖 5. 發(fā)送攜帶 Cookie 的跨域請求
image.png

注意:對于上傳文件等復(fù)雜請求(上傳請求監(jiān)聽了 XMLHttpRequestUpload 以便獲得上傳進(jìn)度)笨使,將觸發(fā)瀏覽器發(fā)送預(yù)檢請求的規(guī)則卿樱,這時(shí)需要在后端服務(wù)器正確響應(yīng) OPTIONS 請求。

總結(jié)

本方案在實(shí)現(xiàn)單點(diǎn)登錄硫椰、構(gòu)建 iframe 門戶頁繁调、攔截鏈接跳轉(zhuǎn)和重置地址欄、改造后端接口共 4 個(gè)方面靶草,漸進(jìn)地整合幾個(gè)關(guān)聯(lián)網(wǎng)站蹄胰,最終達(dá)到一致的用戶體驗(yàn),不僅是看上去一致爱致,而且為統(tǒng)一多個(gè)網(wǎng)站的底層架構(gòu)埋下伏筆烤送。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市糠悯,隨后出現(xiàn)的幾起案子帮坚,更是在濱河造成了極大的恐慌,老刑警劉巖互艾,帶你破解...
    沈念sama閱讀 218,640評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件试和,死亡現(xiàn)場離奇詭異,居然都是意外死亡纫普,警方通過查閱死者的電腦和手機(jī)阅悍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,254評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來昨稼,“玉大人节视,你說我怎么就攤上這事〖偎ǎ” “怎么了寻行?”我有些...
    開封第一講書人閱讀 165,011評論 0 355
  • 文/不壞的土叔 我叫張陵,是天一觀的道長匾荆。 經(jīng)常有香客問我拌蜘,道長杆烁,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,755評論 1 294
  • 正文 為了忘掉前任简卧,我火速辦了婚禮兔魂,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘举娩。我一直安慰自己析校,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,774評論 6 392
  • 文/花漫 我一把揭開白布晓铆。 她就那樣靜靜地躺著勺良,像睡著了一般。 火紅的嫁衣襯著肌膚如雪骄噪。 梳的紋絲不亂的頭發(fā)上尚困,一...
    開封第一講書人閱讀 51,610評論 1 305
  • 那天,我揣著相機(jī)與錄音链蕊,去河邊找鬼事甜。 笑死,一個(gè)胖子當(dāng)著我的面吹牛滔韵,可吹牛的內(nèi)容都是我干的逻谦。 我是一名探鬼主播,決...
    沈念sama閱讀 40,352評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼陪蜻,長吁一口氣:“原來是場噩夢啊……” “哼邦马!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起宴卖,我...
    開封第一講書人閱讀 39,257評論 0 276
  • 序言:老撾萬榮一對情侶失蹤滋将,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后症昏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體随闽,經(jīng)...
    沈念sama閱讀 45,717評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,894評論 3 336
  • 正文 我和宋清朗相戀三年肝谭,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了掘宪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,021評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡攘烛,死狀恐怖魏滚,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情坟漱,我是刑警寧澤栏赴,帶...
    沈念sama閱讀 35,735評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響须眷,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜沟突,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,354評論 3 330
  • 文/蒙蒙 一花颗、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧惠拭,春花似錦扩劝、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,936評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至域携,卻和暖如春簇秒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背秀鞭。 一陣腳步聲響...
    開封第一講書人閱讀 33,054評論 1 270
  • 我被黑心中介騙來泰國打工趋观, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人锋边。 一個(gè)月前我還...
    沈念sama閱讀 48,224評論 3 371
  • 正文 我出身青樓皱坛,卻偏偏與公主長得像,于是被迫代替她去往敵國和親豆巨。 傳聞我的和親對象是個(gè)殘疾皇子剩辟,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,974評論 2 355

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

  • 什么是跨域 跨域,是指瀏覽器不能執(zhí)行其他網(wǎng)站的腳本往扔。它是由瀏覽器的同源策略造成的贩猎,是瀏覽器對JavaScript實(shí)...
    Yaoxue9閱讀 1,299評論 0 6
  • 什么是跨域 跨域,是指瀏覽器不能執(zhí)行其他網(wǎng)站的腳本瓤球。它是由瀏覽器的同源策略造成的融欧,是瀏覽器對JavaScript實(shí)...
    他方l閱讀 1,064評論 0 2
  • 什么是跨域 跨域,是指瀏覽器不能執(zhí)行其他網(wǎng)站的腳本卦羡。它是由瀏覽器的同源策略造成的噪馏,是瀏覽器對JavaScript實(shí)...
    HeroXin閱讀 836評論 0 4
  • 1. 什么是跨域? 跨域一詞從字面意思看绿饵,就是跨域名嘛欠肾,但實(shí)際上跨域的范圍絕對不止那么狹隘。具體概念如下:只要協(xié)議...
    w_zhuan閱讀 518評論 0 0
  • 1. 什么是跨域拟赊? 跨域一詞從字面意思看刺桃,就是跨域名嘛,但實(shí)際上跨域的范圍絕對不止那么狹隘吸祟。具體概念如下:只要協(xié)議...
    他在發(fā)呆閱讀 822評論 0 0