15 Go 鑒權(quán)(一):鑒權(quán)機(jī)制概述

一蛋逾、系統(tǒng)鑒權(quán)概述

在現(xiàn)代web開發(fā)中白对,系統(tǒng)鑒權(quán)服務(wù)已是基本標(biāo)配模塊,有些開發(fā)框架甚至內(nèi)置了鑒權(quán)模塊的實(shí)現(xiàn)换怖,或者提供一些鑒權(quán)的工具類,然而鑒權(quán)的方式也分為多種蟀瞧,了解各種鑒權(quán)方式的特點(diǎn)及使用場景可以幫助我們構(gòu)建更健壯的web系統(tǒng)沉颂。以下列出四種常見的鑒權(quán)方式条摸,我們來認(rèn)識一下:

  • HTTP Basic Authentication
  • Session-Cookie機(jī)制
  • Token令牌機(jī)制
  • OAuth2.0授權(quán)機(jī)制

二、鑒權(quán)方式簡析

1.HTTP Basic Authentication

HTTP 基本身份驗(yàn)證铸屉,允許客戶端在標(biāo)準(zhǔn)的 HTTP 頭中發(fā)送用戶名和密碼钉蒲。服務(wù)端可以驗(yàn)證這些信息,并確認(rèn)客戶端是否有權(quán)訪問服務(wù)彻坛。這樣做的好處在于顷啼,這是一種非常容易理解且得到廣泛支持的協(xié)議。問題在于昌屉,通過 HTTP 有很高的風(fēng)險(xiǎn)钙蒙,因?yàn)橛脩裘兔艽a并沒有以安全的方式發(fā)送。任何中間方都可以看到 HTTP 頭的信息并讀取里面的數(shù)據(jù)间驮。因此躬厌,HTTP 基本身份驗(yàn)證通常應(yīng)該通過 HTTPS 進(jìn)行通信。

當(dāng)使用 HTTPS 時(shí)竞帽,客戶端獲得強(qiáng)有力的保證扛施,它所通信的服務(wù)端就是客戶端想要通信的服務(wù)端。它給予我們額外的保護(hù)屹篓,避免人們竊聽客戶端和服務(wù)端之間的通信疙渣,或篡改有效負(fù)載。

服務(wù)端需要管理自己的SSL證書堆巧,當(dāng)需要管理多臺機(jī)器時(shí)會出現(xiàn)問題妄荔。一些組織自己承擔(dān)簽發(fā)證書的過程,這是一個(gè)額外的行政和運(yùn)營負(fù)擔(dān)恳邀。管理這方面的自動化工具遠(yuǎn)不夠成熟懦冰,使用它們后你會發(fā)現(xiàn),需要自己處理的事情就不止證書簽發(fā)了谣沸。自簽名證書不容易撤銷刷钢,因此需要對災(zāi)難情景有更多的考慮∪楦剑看看你是否能夠避免自簽名内地,以避開所有的這些工作。

SSL 之上的流量不能被反向代理服務(wù)器(比如 Varnish 或 Squid)所緩存赋除,這是使用 HTTPS 的另一個(gè)缺點(diǎn)阱缓。這意味著,如果你需要緩存信息举农,就不得不在服務(wù)端或客戶端內(nèi)部實(shí)現(xiàn)荆针。你可以在負(fù)載均衡中把 Https 的請求轉(zhuǎn)成 Http 的請求,然后在負(fù)載均衡之后就可以使用緩存了。

還需要考慮航背,如果我們已經(jīng)在使用現(xiàn)成的 SSO 方案(比如包含用戶名密碼信息的 SAML)喉悴,該怎么辦。我們想要基本身份驗(yàn)證使用同一套認(rèn)證信息玖媚,然后在同一個(gè)進(jìn)程里頒發(fā)和撤銷嗎箕肃?讓服務(wù)與實(shí)現(xiàn) SSO 所使用的那個(gè)目錄服務(wù)進(jìn)行通信即可做到這一點(diǎn)〗衲В或者勺像,我們可以在服務(wù)內(nèi)部存儲用戶名和密碼,但需要承擔(dān)存在重復(fù)行為的風(fēng)險(xiǎn)错森。

注意:使用這種方法吟宦,服務(wù)器只知道客戶端有用戶名和密碼。我們不知道這個(gè)信息是否來自我們期望的機(jī)器问词;它可能來自網(wǎng)絡(luò)中的其他人督函。

1.HTTP_BASE_AUTH.jpg

HTTP 基本身份驗(yàn)證是一種簡單但不那么安全的認(rèn)證方式,不太建議用于公開的商業(yè)應(yīng)用激挪,在此便不再展開辰狡,我們關(guān)注以下幾種認(rèn)證方式。

2.Session-Cookie

http協(xié)議是一種無狀態(tài)的協(xié)議垄分,如果沒有任何認(rèn)證機(jī)制宛篇,服務(wù)端對任何客戶端的請求都是無差別的。在Web2.0時(shí)代薄湿,為了加強(qiáng)B/S交互的安全性叫倍,衍生出了Session-Cookie鑒權(quán)機(jī)制,通過在服務(wù)端開啟會話豺瘤,客戶端存儲SessionID吆倦,在每次請求時(shí)通過cookie傳輸SessionID的形式實(shí)現(xiàn)服務(wù)端基本鑒權(quán)。

Cookie

cookie是保存在本地終端的數(shù)據(jù)坐求。cookie由服務(wù)器生成蚕泽,發(fā)送給瀏覽器,瀏覽器把cookie以kv形式保存到某個(gè)目錄下的文本文件內(nèi)桥嗤,下一次請求同一網(wǎng)站時(shí)會把該cookie發(fā)送給服務(wù)器须妻。由于cookie是存在客戶端上的,所以瀏覽器加入了一些限制確保cookie不會被惡意使用泛领,同時(shí)不會占據(jù)太多磁盤空間荒吏,所以每個(gè)域的cookie數(shù)量是有限的。

cookie的組成有:名稱(key)渊鞋、值(value)绰更、有效域(domain)瞧挤、路徑(域的路徑,一般設(shè)置為全局:"")动知、失效時(shí)間皿伺、安全標(biāo)志(指定后,cookie只有在使用SSL連接時(shí)才發(fā)送到服務(wù)器(https))盒粮。

Session

Session的中文翻譯是“會話”,當(dāng)用戶打開某個(gè)web應(yīng)用時(shí)奠滑,便與web服務(wù)器產(chǎn)生一次session丹皱。服務(wù)器使用session把用戶的信息臨時(shí)保存在了服務(wù)器上,用戶離開網(wǎng)站后session會被銷毀宋税。這種用戶信息存儲方式相對cookie來說更安全摊崭,可是session有一個(gè)缺陷:如果web服務(wù)器做了負(fù)載均衡,那么下一個(gè)操作請求到了另一臺服務(wù)器的時(shí)候session會丟失杰赛。

當(dāng)程序需要為某個(gè)客戶端的請求創(chuàng)建一個(gè)session時(shí)呢簸,服務(wù)器首先檢查這個(gè)客戶端的請求里是否已包含了一個(gè)session標(biāo)識(稱為SessionID),如果已包含則說明以前已經(jīng)為此客戶端創(chuàng)建過Session乏屯,服務(wù)器就按照SessionID把這個(gè)Session檢索出來使用(檢索不到根时,會新建一個(gè)),如果客戶端請求不包含SessionID辰晕,則為此客戶端創(chuàng)建一個(gè)Session并且生成一個(gè)與此Session相關(guān)聯(lián)的SessionID蛤迎,SessionID的值應(yīng)該是一個(gè)既不會重復(fù),又不容易被找到規(guī)律以仿造的字符串含友,這個(gè)SessionID將被在本次響應(yīng)中返回給客戶端保存替裆。

保存這個(gè)SessionID的方式可以采用Cookie,這樣在交互過程中瀏覽器可以自動的按照規(guī)則把這個(gè)標(biāo)識發(fā)揮給服務(wù)器窘问。一般這個(gè)Cookie的名字都是類似于SEEESIONID辆童。但Cookie可以被人為的禁止,則必須有其他機(jī)制以便在Cookie被禁止時(shí)仍然能夠把SessionID傳遞回服務(wù)器惠赫。

基本鑒權(quán)機(jī)制:

客戶端第一次發(fā)送請求給服務(wù)器把鉴,此時(shí)服務(wù)器啟動Session會話,產(chǎn)生一個(gè)唯一的SessionID汉形,并通過Response的SetCookie返回給客戶端纸镊,保存于客戶端(一般為瀏覽器),并與一個(gè)瀏覽器窗口對應(yīng)著,由于HTTP協(xié)議的特性概疆,這一次Request-Response
后連接就斷開了逗威。以后此客戶端再發(fā)送請求給服務(wù)器的時(shí)候,就會在請求Request頭中攜帶cookie,由于cookie中帶有Key為sessionID的數(shù)據(jù),所以服務(wù)器就知道這是剛才那個(gè)客戶端岔冀。

Base Session-Cookie Authentication
2.SessionCookie.jpg

Go官方?jīng)]有提供Session管理器的實(shí)現(xiàn)凯旭,Github上的開源項(xiàng)目beego實(shí)現(xiàn)了一個(gè)Session管理器,有興趣的可看以下轉(zhuǎn)載文章:《Go 鑒權(quán)之Session》

3.Token

正如我們前面所討論的,如果擔(dān)心用戶名和密碼被泄露罐呼,HTTP基本身份驗(yàn)證使用普通 HTTP 并不是非常明智的鞠柄。傳統(tǒng)的替代方式是使用HTTPS路由通信,但也有一些缺點(diǎn)嫉柴。除了需要管理證書厌杜,HTTPS通信的開銷使得服務(wù)器壓力增加,而且通信難以被輕松地緩存计螺。另外Session-Cookie機(jī)制也會有被客戶限制的隱患夯尽,如果用戶禁用Cookie則必須由其它方式實(shí)現(xiàn)鑒權(quán)。

所謂Token登馒,即令牌匙握。客戶端需要鑒權(quán)訪問私人信息時(shí)陈轿,會首次向服務(wù)端發(fā)送身份驗(yàn)證信息(如用戶名圈纺、密碼),服務(wù)端校驗(yàn)正確后會根據(jù)一定的加密算法生成Token令牌發(fā)放給客戶端麦射,此后客戶端只需通過Token蛾娶,服務(wù)端只需驗(yàn)證Token就可識別客戶并進(jìn)行交互,Token可存放于HTTP Header也可存放與Cookie法褥。

3.Token.jpg

以上為一個(gè)簡單的Token鑒權(quán)過程茫叭。

JWT

關(guān)于Token機(jī)制,業(yè)界有一種叫JWT(JsonWebToken)的實(shí)現(xiàn)機(jī)制半等,下面我們來了解JWT揍愁。

JWT.io 對JSON Web Tokens進(jìn)行了很好的介紹,
國內(nèi)阮一峰的《JSON Web Token 入門教程》也講得非常好懂杀饵,可以出門右拐了解一下莽囤。

簡而言之,它是一個(gè)簽名的JSON對象切距,可以執(zhí)行一些有用的操作(例如朽缎,身份驗(yàn)證)。它是一組字串谜悟,分Header(頭部)话肖、Payload(負(fù)載)、Signature(簽名)三部分葡幸,由'.'號連接最筒,看起來就像下面這樣:

Header.Payload.Signature

用戶發(fā)送認(rèn)證信息給服務(wù)端后,服務(wù)端通過JWT生成規(guī)則蔚叨,生成JWT字串作為Token發(fā)放給用戶床蜘,用戶以后每次訪問都在HTTP Header攜帶JWT字串辙培,已達(dá)到鑒權(quán)目的。由于其內(nèi)部攜帶用戶信息邢锯,部分使用者已經(jīng)發(fā)現(xiàn)其安全隱患扬蕊,但其安全度不至于太過容易破解,在移動應(yīng)用中的鑒權(quán)機(jī)制使用較多丹擎,除此之外尾抑,一些分布式的微服務(wù)應(yīng)用也通過JWT進(jìn)行模塊間的鑒權(quán),還是有一定的使用場景的鸥鹉。

Go開源社區(qū)已有比較成熟的JWT包實(shí)現(xiàn):jwt-go 蛮穿,內(nèi)附有JWT編解碼的使用用例,還是很好懂的毁渗,感興趣的可get來使用。在另一篇中也做了Go 使用JWT鑒權(quán)的示例:《Go 鑒權(quán)(三):JWT》,感興趣可閱讀以下单刁,自己也在項(xiàng)目中實(shí)踐一下灸异。

4.OAuth2.0(開放授權(quán))

OAUTH協(xié)議為用戶資源的授權(quán)提供了一個(gè)安全的、開放而又簡易的標(biāo)準(zhǔn)羔飞。同時(shí)肺樟,任何第三方都可以使用OAUTH認(rèn)證服務(wù),任何服務(wù)提供商都可以實(shí)現(xiàn)自身的OAUTH認(rèn)證服務(wù)逻淌,因而OAUTH是開放的么伯。

OpenID Connect 是 OAuth 2.0 具體實(shí)現(xiàn)中的一個(gè)標(biāo)準(zhǔn)。它使用簡單的 REST 調(diào)用卡儒,因?yàn)樘岣吡似湟子眯蕴锶帷τ谝粋€(gè)面向公眾的網(wǎng)站,你或許可以使用Google骨望、Facebook硬爆、Github等作為提供者,國內(nèi)可以使用QQ擎鸠、微信缀磕、淘寶等作為提供者。但對于內(nèi)部系統(tǒng)劣光,或?qū)τ跀?shù)據(jù)需要有更多控制權(quán)的系統(tǒng)而言袜蚕,你會希望有自己的內(nèi)部身份提供者。

OAuth2.0有四種授權(quán)模式绢涡,具體可看阮一峰的《理解OAuth2.0》,其內(nèi)容非常詳細(xì)且好理解牲剃。

我們這里說一下最完整的授權(quán)碼模式:

4.OAuth.jpg
  • 用戶:如用戶瀏覽器
  • 目標(biāo)應(yīng)用服務(wù):如簡書
  • 服務(wù)商資源擁有者:如已登錄的QQ用戶
  • 服務(wù)商認(rèn)證服務(wù)器:如QQ認(rèn)證服務(wù)器
  • 服務(wù)商資源服務(wù)器:如QQ用戶資源服務(wù)器

以上為OAuth2.0的認(rèn)證過程。

  • 如你只需實(shí)現(xiàn)三方授權(quán)登錄這種鑒權(quán)機(jī)制

各大廠都有提供基于OAuth2.0的三方授權(quán)服務(wù)垂寥,如QQ颠黎、微信另锋、淘寶等等,有需要可移步到各自的開放平臺查看文檔狭归,大都有提供Go的接口實(shí)現(xiàn)夭坪;另你也可參考使用Go官方提供實(shí)現(xiàn)的包 https://github.com/golang/oauth2,里面包含多數(shù)熱門的OAuth客戶端过椎。

  • 如你需要構(gòu)建自己的OAuth認(rèn)證服務(wù)

推薦使用 https://github.com/ory/hydra 這個(gè)開源項(xiàng)目室梅,幫助你構(gòu)建自己的OAuth服務(wù)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市疚宇,隨后出現(xiàn)的幾起案子亡鼠,更是在濱河造成了極大的恐慌,老刑警劉巖敷待,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件间涵,死亡現(xiàn)場離奇詭異,居然都是意外死亡榜揖,警方通過查閱死者的電腦和手機(jī)勾哩,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來举哟,“玉大人思劳,你說我怎么就攤上這事》列桑” “怎么了潜叛?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長壶硅。 經(jīng)常有香客問我威兜,道長,這世上最難降的妖魔是什么森瘪? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任牡属,我火速辦了婚禮,結(jié)果婚禮上扼睬,老公的妹妹穿的比我還像新娘逮栅。我一直安慰自己,他們只是感情好窗宇,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布措伐。 她就那樣靜靜地躺著,像睡著了一般军俊。 火紅的嫁衣襯著肌膚如雪侥加。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天粪躬,我揣著相機(jī)與錄音担败,去河邊找鬼昔穴。 笑死,一個(gè)胖子當(dāng)著我的面吹牛提前,可吹牛的內(nèi)容都是我干的吗货。 我是一名探鬼主播,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼狈网,長吁一口氣:“原來是場噩夢啊……” “哼宙搬!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起拓哺,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤勇垛,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后士鸥,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體闲孤,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年烤礁,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了崭放。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,561評論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡鸽凶,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出建峭,到底是詐尸還是另有隱情玻侥,我是刑警寧澤,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布亿蒸,位于F島的核電站凑兰,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏边锁。R本人自食惡果不足惜姑食,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望茅坛。 院中可真熱鬧音半,春花似錦、人聲如沸贡蓖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽斥铺。三九已至彻桃,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間晾蜘,已是汗流浹背邻眷。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工眠屎, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人肆饶。 一個(gè)月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓改衩,卻偏偏與公主長得像,于是被迫代替她去往敵國和親抖拴。 傳聞我的和親對象是個(gè)殘疾皇子燎字,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,573評論 2 359