Oauth 2.0 學(xué)習(xí)筆記

定義

  • OAuth是一個關(guān)于授權(quán)(authorization)的開放網(wǎng)絡(luò)標(biāo)準(zhǔn)涣狗,在全世界得到廣泛應(yīng)用,目前的版本是2.0版
    舉例: OAuth 就是一種授權(quán)機制跪呈。數(shù)據(jù)的所有者告訴系統(tǒng)妇汗,同意授權(quán)第三方應(yīng)用進(jìn)入系統(tǒng)孩革,獲取這些數(shù)據(jù)际歼。系統(tǒng)從而產(chǎn)生一個短期的進(jìn)入令牌(token)惶翻,用來代替密碼,供第三方應(yīng)用使用鹅心。
  • 令牌(token)與密碼(password)
    相同點
    作用是一樣的吕粗,都可以進(jìn)入系統(tǒng),但是有三點差異
    不同點
    (1)令牌是短期的巴帮,到期會自動失效溯泣,用戶自己無法修改虐秋。密碼一般長期有效榕茧,用戶不修改,就不會發(fā)生變化客给。
    (2)令牌可以被數(shù)據(jù)所有者撤銷用押,會立即失效。以上例而言靶剑,屋主可以隨時取消快遞員的令牌蜻拨。密碼一般不允許被他人撤銷。
    (3)令牌有權(quán)限范圍(scope)桩引,比如只能進(jìn)小區(qū)的二號門缎讼。對于網(wǎng)絡(luò)服務(wù)來說,只讀令牌就比讀寫令牌更安全坑匠。密碼一般是完整權(quán)限血崭。
  • 令牌使用
    A 網(wǎng)站拿到令牌以后,就可以向 B 網(wǎng)站的 API 請求數(shù)據(jù)了
    每個發(fā)到 API 的請求,都必須帶有令牌
    具體做法是在請求的頭信息夹纫,加上一個Authorization字段咽瓷,令牌就放在這個字段里面。
  curl -H "Authorization: Bearer ACCESS_TOKEN" \"[https://api.b.com](https://api.b.com/)"

上面命令中舰讹,ACCESS_TOKEN就是拿到的令牌茅姜。

  • 令牌更新
    令牌的有效期到了
    具體方法是,B 網(wǎng)站頒發(fā)令牌的時候月匣,一次性頒發(fā)兩個令牌钻洒,一個用于獲取數(shù)據(jù),另一個用于獲取新的令牌(refresh token 字段)桶错。令牌到期前航唆,用戶使用 refresh token 發(fā)一個請求,去更新令牌院刁。B 網(wǎng)站驗證通過以后糯钙,就會頒發(fā)新的令牌。
    https://b.com/oauth/token?grant_type=refresh_token&client_id=CLIENT_ID&client_secret=CLIENT_SECRET&refresh_token=REFRESH_TOKEN
    上面 URL 中退腥,grant_type參數(shù)為refresh_token表示要求更新令牌任岸,client_id參數(shù)和client_secret參數(shù)用于確認(rèn)身份,refresh_token參數(shù)就是用于更新令牌的令牌狡刘。

4種授權(quán)方式

4種授權(quán)類型.png

舉例:授權(quán)碼

AB.png

第一步享潜,A 網(wǎng)站提供一個鏈接,用戶點擊后就會跳轉(zhuǎn)到 B 網(wǎng)站嗅蔬,授權(quán)用戶數(shù)據(jù)給 A 網(wǎng)站使用剑按。下面就是 A 網(wǎng)站跳轉(zhuǎn) B 網(wǎng)站的一個示意鏈接。

https://b.com/oauth/authorize?
  response_type=code&
  client_id=CLIENT_ID&
  redirect_uri=CALLBACK_URL&
  scope=read

上面 URL 中澜术,response_type參數(shù)表示要求返回授權(quán)碼(code)艺蝴,client_id參數(shù)讓 B 知道是誰在請求,redirect_uri參數(shù)是 B 接受或拒絕請求后的跳轉(zhuǎn)網(wǎng)址鸟废,scope參數(shù)表示要求的授權(quán)范圍(這里是只讀)猜敢。

第二步,用戶跳轉(zhuǎn)后盒延,B 網(wǎng)站會要求用戶登錄缩擂,然后詢問是否同意給予 A 網(wǎng)站授權(quán)。用戶表示同意添寺,這時 B 網(wǎng)站就會跳回redirect_uri參數(shù)指定的網(wǎng)址胯盯。跳轉(zhuǎn)時,會傳回一個授權(quán)碼计露,就像下面這樣

https://a.com/callback?code=AUTHORIZATION_CODE

上面 URL 中博脑,code參數(shù)就是授權(quán)碼楞捂。

第三步,A 網(wǎng)站拿到授權(quán)碼以后趋厉,就可以在后端寨闹,向 B 網(wǎng)站請求令牌。

https://b.com/oauth/token?
 client_id=CLIENT_ID&
 client_secret=CLIENT_SECRET&
 grant_type=authorization_code&
 code=AUTHORIZATION_CODE&
 redirect_uri=CALLBACK_URL

上面 URL 中君账,client_id參數(shù)和client_secret參數(shù)用來讓 B 確認(rèn) A 的身份(client_secret參數(shù)是保密的繁堡,因此只能在后端發(fā)請求),grant_type參數(shù)的值是AUTHORIZATION_CODE乡数,表示采用的授權(quán)方式是授權(quán)碼椭蹄,code參數(shù)是上一步拿到的授權(quán)碼,redirect_uri參數(shù)是令牌頒發(fā)后的回調(diào)網(wǎng)址净赴。

第四步绳矩,B 網(wǎng)站收到請求以后,就會頒發(fā)令牌玖翅。具體做法是向redirect_uri指定的網(wǎng)址翼馆,發(fā)送一段 JSON 數(shù)據(jù)。

{    
  "access_token":"ACCESS_TOKEN",
  "token_type":"bearer",
  "expires_in":2592000,
  "refresh_token":"REFRESH_TOKEN",
  "scope":"read",
  "uid":100101,
  "info":{...}
}

上面 JSON 數(shù)據(jù)中金度,access_token字段就是令牌应媚,A 網(wǎng)站在后端拿到了。

Demo


下載源碼

源碼github鏈接: 網(wǎng)上提供的代碼倉庫猜极,請將它克隆到本地中姜。

$ git clone git@github.com:ruanyf/node-oauth-demo.git
$ cd node-oauth-demo

兩個配置項要改一下,寫入上一步的身份識別碼跟伏。

然后丢胚,安裝依賴。

$ npm install

啟動服務(wù)受扳。

$ node index.js

瀏覽器訪問[http://localhost:8080](http://localhost:8080/)携龟,就可以看到這個示例了。

login.jpeg


查看授權(quán)頁面

示例的首頁很簡單辞色,就是一個鏈接骨宠,讓用戶跳轉(zhuǎn)到 GitHub浮定。

authorization.png

跳轉(zhuǎn)的 URL 如下相满。

https://github.com/login/oauth/authorize?
  client_id=7e015d8ce32370079895&
  redirect_uri=http://localhost:8080/oauth/redirect

這個 URL 指向 GitHub 的 OAuth 授權(quán)網(wǎng)址,帶有兩個參數(shù):client_id告訴 GitHub 誰在請求克婶,redirect_uri是稍后跳轉(zhuǎn)回來的網(wǎng)址绊谭。
用戶點擊到了 GitHub脖苏,GitHub 會要求用戶登錄,確保是本人在操作建蹄。
登錄后碌更,GitHub 詢問用戶,該應(yīng)用正在請求數(shù)據(jù)洞慎,你是否同意授權(quán)痛单。
[圖片上傳中...(code.png-7e7999-1645355031998-0)]

用戶同意授權(quán), GitHub 就會跳轉(zhuǎn)到redirect_uri指定的跳轉(zhuǎn)網(wǎng)址劲腿,并且?guī)鲜跈?quán)碼旭绒,跳轉(zhuǎn)回來的 URL 就是下面的樣子。

http://localhost:8080/oauth/redirect?code=859310e7cecc9196f4af

后端收到這個請求以后焦人,就拿到了授權(quán)碼(code參數(shù))挥吵。

后端實現(xiàn)

示例的后端采用 Koa 框架編寫,具體語法請看教程花椭。
這里的關(guān)鍵是針對/oauth/redirect的請求忽匈,編寫一個路由,完成 OAuth 認(rèn)證矿辽。


const oauth = async ctx => {
  // ...
};

app.use(route.get('/oauth/redirect', oauth));

上面代碼中丹允,oauth函數(shù)就是路由的處理函數(shù)。下面的代碼都寫在這個函數(shù)里面袋倔。

路由函數(shù)的第一件事嫌松,是從 URL 取出授權(quán)碼。

const requestToken = ctx.request.query.code;

后端使用這個授權(quán)碼奕污,向 GitHub 請求令牌萎羔。

const tokenResponse = await axios({
  method: 'post',
  url: 'https://github.com/login/oauth/access_token?' +
    `client_id=${clientID}&` +
    `client_secret=${clientSecret}&` +
    `code=${requestToken}`,
  headers: {
    accept: 'application/json'
  }
});

上面代碼中,GitHub 的令牌接口[https://github.com/login/oauth/access_token](https://github.com/login/oauth/access_token)需要提供三個參數(shù)碳默。

  • client_id:客戶端的 ID
  • client_secret:客戶端的密鑰
  • code:授權(quán)碼
    作為回應(yīng)贾陷,GitHub 會返回一段 JSON 數(shù)據(jù),里面包含了令牌accessToken嘱根。const accessToken = tokenResponse.data.access_token髓废;

API數(shù)據(jù)

有了令牌以后,就可以向 API 請求數(shù)據(jù)了该抒。

const result = await axios({
  method: 'get',
  url: `https://api.github.com/user`,
  headers: {
    accept: 'application/json',
    Authorization: `token ${accessToken}`
  }
});

上面代碼中慌洪,GitHub API 的地址是[https://api.github.com/user](https://api.github.com/user),請求的時候必須在 HTTP 頭信息里面帶上令牌Authorization: token 361507da凑保。

然后冈爹,就可以拿到用戶數(shù)據(jù),得到用戶的身份欧引。

const name = result.data.name;
ctx.response.redirect(`/welcome.html?name=${name}`);

總結(jié):


![AB.png](https://upload-images.jianshu.io/upload_images/4762081-052eeb1c4cd52dde.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)

相關(guān)文檔

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末频伤,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子芝此,更是在濱河造成了極大的恐慌憋肖,老刑警劉巖因痛,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異岸更,居然都是意外死亡鸵膏,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進(jìn)店門怎炊,熙熙樓的掌柜王于貴愁眉苦臉地迎上來较性,“玉大人,你說我怎么就攤上這事结胀≡蘖” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵糟港,是天一觀的道長攀操。 經(jīng)常有香客問我,道長秸抚,這世上最難降的妖魔是什么速和? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮剥汤,結(jié)果婚禮上颠放,老公的妹妹穿的比我還像新娘。我一直安慰自己吭敢,他們只是感情好碰凶,可當(dāng)我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著鹿驼,像睡著了一般欲低。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上畜晰,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天砾莱,我揣著相機與錄音,去河邊找鬼凄鼻。 笑死腊瑟,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的块蚌。 我是一名探鬼主播闰非,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼匈子!你這毒婦竟也來了河胎?” 一聲冷哼從身側(cè)響起闯袒,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤虎敦,失蹤者是張志新(化名)和其女友劉穎游岳,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體其徙,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡胚迫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了唾那。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片访锻。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖闹获,靈堂內(nèi)的尸體忽然破棺而出期犬,到底是詐尸還是另有隱情,我是刑警寧澤避诽,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布龟虎,位于F島的核電站,受9級特大地震影響沙庐,放射性物質(zhì)發(fā)生泄漏鲤妥。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一拱雏、第九天 我趴在偏房一處隱蔽的房頂上張望棉安。 院中可真熱鬧,春花似錦铸抑、人聲如沸贡耽。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽菇爪。三九已至,卻和暖如春柒昏,著一層夾襖步出監(jiān)牢的瞬間凳宙,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工职祷, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留氏涩,地道東北人。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓有梆,卻偏偏與公主長得像是尖,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子泥耀,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,435評論 2 359

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