這組 OAuth 系列教程,第一篇介紹了基本概念,第二篇介紹了獲取令牌的四種方式,今天演示一個(gè)實(shí)例,如何通過 OAuth 獲取 API 數(shù)據(jù)。
很多網(wǎng)站登錄時(shí),允許使用第三方網(wǎng)站的身份,這稱為"第三方登錄"。
下面就以 GitHub 為例,寫一個(gè)最簡(jiǎn)單的應(yīng)用,演示第三方登錄。
所謂第三方登錄,實(shí)質(zhì)就是 OAuth 授權(quán)。用戶想要登錄 A 網(wǎng)站,A 網(wǎng)站讓用戶提供第三方網(wǎng)站的數(shù)據(jù),證明自己的身份。獲取第三方網(wǎng)站的身份數(shù)據(jù),就需要 OAuth 授權(quán)。
舉例來說,A 網(wǎng)站允許 GitHub 登錄,背后就是下面的流程。
- A 網(wǎng)站讓用戶跳轉(zhuǎn)到 GitHub。
- GitHub 要求用戶登錄,然后詢問"A 網(wǎng)站要求獲得 xx 權(quán)限,你是否同意?"
- 用戶同意,GitHub 就會(huì)重定向回 A 網(wǎng)站,同時(shí)發(fā)回一個(gè)授權(quán)碼。
- A 網(wǎng)站使用授權(quán)碼,向 GitHub 請(qǐng)求令牌。
- GitHub 返回令牌.
- A 網(wǎng)站使用令牌,向 GitHub 請(qǐng)求用戶數(shù)據(jù)。
下面就是這個(gè)流程的代碼實(shí)現(xiàn)。
一個(gè)應(yīng)用要求 OAuth 授權(quán),必須先到對(duì)方網(wǎng)站登記,讓對(duì)方知道是誰在請(qǐng)求。
所以,你要先去 GitHub 登記一下。當(dāng)然,我已經(jīng)登記過了,你使用我的登記信息也可以,但為了完整走一遍流程,還是建議大家自己登記。這是免費(fèi)的。
訪問這個(gè)網(wǎng)址,填寫登記表。
應(yīng)用的名稱隨便填,主頁(yè) URL 填寫http://localhost:8080
,跳轉(zhuǎn)網(wǎng)址填寫 http://localhost:8080/oauth/redirect
。
提交表單以后,GitHub 應(yīng)該會(huì)返回客戶端 ID(client ID)和客戶端密鑰(client secret),這就是應(yīng)用的身份識(shí)別碼。
我寫了一個(gè)代碼倉(cāng)庫(kù),請(qǐng)將它克隆到本地。
$ git clone git@github.com:ruanyf/node-oauth-demo.git$ cd node-oauth-demo
兩個(gè)配置項(xiàng)要改一下,寫入上一步的身份識(shí)別碼。
- index.js:改掉變量
clientID
andclientSecret
- public/index.html:改掉變量
client_id
然后,安裝依賴。
$ npm install
啟動(dòng)服務(wù)。
$ node index.js
瀏覽器訪問http://localhost:8080
,就可以看到這個(gè)示例了。
示例的首頁(yè)很簡(jiǎn)單,就是一個(gè)鏈接,讓用戶跳轉(zhuǎn)到 GitHub。
跳轉(zhuǎn)的 URL 如下。
https://github.com/login/oauth/authorize? client_id=7e015d8ce32370079895& redirect_uri=http://localhost:8080/oauth/redirect
這個(gè) URL 指向 GitHub 的 OAuth 授權(quán)網(wǎng)址,帶有兩個(gè)參數(shù):client_id
告訴 GitHub 誰在請(qǐng)求,redirect_uri
是稍后跳轉(zhuǎn)回來的網(wǎng)址。
用戶點(diǎn)擊到了 GitHub,GitHub 會(huì)要求用戶登錄,確保是本人在操作。
登錄后,GitHub 詢問用戶,該應(yīng)用正在請(qǐng)求數(shù)據(jù),你是否同意授權(quán)。
用戶同意授權(quán), GitHub 就會(huì)跳轉(zhuǎn)到redirect_uri
指定的跳轉(zhuǎn)網(wǎng)址,并且?guī)鲜跈?quán)碼,跳轉(zhuǎn)回來的 URL 就是下面的樣子。
http://localhost:8080/oauth/redirect? code=859310e7cecc9196f4af
后端收到這個(gè)請(qǐng)求以后,就拿到了授權(quán)碼(code
參數(shù))。
示例的后端采用 Koa 框架編寫,具體語(yǔ)法請(qǐng)看教程。
這里的關(guān)鍵是針對(duì)/oauth/redirect
的請(qǐng)求,編寫一個(gè)路由,完成 OAuth 認(rèn)證。
const oauth = async ctx => { // ...};app.use(route.get('/oauth/redirect', oauth));
上面代碼中,oauth
函數(shù)就是路由的處理函數(shù)。下面的代碼都寫在這個(gè)函數(shù)里面。
路由函數(shù)的第一件事,是從 URL 取出授權(quán)碼。
const requestToken = ctx.request.query.code;
后端使用這個(gè)授權(quán)碼,向 GitHub 請(qǐng)求令牌。
const tokenResponse = await axios({ method: 'post', url: '
上面代碼中,GitHub 的令牌接口https://github.com/login/oauth/access_token
需要提供三個(gè)參數(shù)。
client_id
:客戶端的 IDclient_secret
:客戶端的密鑰code
:授權(quán)碼
作為回應(yīng),GitHub 會(huì)返回一段 JSON 數(shù)據(jù),里面包含了令牌accessToken
。
const accessToken = tokenResponse.data.access_token;
有了令牌以后,就可以向 API 請(qǐng)求數(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
,請(qǐng)求的時(shí)候必須在 HTTP 頭信息里面帶上令牌Authorization: token 361507da
。
然后,就可以拿到用戶數(shù)據(jù),得到用戶的身份。
const name = result.data.name;ctx.response.redirect(`/welcome.html?name=${name}`);
(完)
聯(lián)系客服