慣性聚合 高效追蹤和閱讀你感興趣的部落格、新聞、科技資訊
閱讀原文 在慣性聚合中打開

推薦訂閱源

博客园 - 司徒正美
V
V2EX
T
Tailwind CSS Blog
有赞技术团队
有赞技术团队
aimingoo的专栏
aimingoo的专栏
Apple Machine Learning Research
Apple Machine Learning Research
IT之家
IT之家
Blog — PlanetScale
Blog — PlanetScale
A
About on SuperTechFans
月光博客
月光博客
T
The Blog of Author Tim Ferriss
宝玉的分享
宝玉的分享
Martin Fowler
Martin Fowler
博客园 - 聂微东
The GitHub Blog
The GitHub Blog
V
Visual Studio Blog
WordPress大学
WordPress大学
酷 壳 – CoolShell
酷 壳 – CoolShell
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI

阮一峰的网络日志

科技爱好者周刊(第 396 期):互联网通信的替代方案 科技爱好者周刊(第 396 期):互联网通信的替代方案 - 阮一峰的网络日志 科技爱好者周刊(第 395 期):软件开发的第三种方式 科技爱好者周刊(第 395 期):软件开发的第三种方式 - 阮一峰的网络日志 科技爱好者周刊(第 393 期):脑腐状态 科技爱好者周刊(第 392 期):axios 投毒与好莱坞式骗术 科技爱好者周刊(第 391 期):AI 的贫富分化 科技爱好者周刊(第 390 期):没有语料,大模型就是智障 套壳中国大模型撑起500亿美元估值?扒一扒 Cursor 的"套壳"疑云 科技爱好者周刊(第 389 期):未来如何招聘程序员 科技爱好者周刊(第 388 期):测试是新的护城河 零安装的"云养虾":ArkClaw 使用指南 科技爱好者周刊(第 387 期):你是领先的 科技爱好者周刊(第 386 期):当外卖员接入 AI 字节全家桶 Seed 2.0 + TRAE 玩转 Skill 科技爱好者周刊(第 385 期):马斯克害怕中国车企吗? 智谱旗舰 GLM-5 实测:对比 Opus 4.6 和 GPT-5.3-Codex 科技爱好者周刊(第 384 期):为什么软件股下跌 科技爱好者周刊(第 383 期):你是第几级 AI 编程 Kimi 的一体化,Manus 的分层 科技爱好者周刊(第 382 期):独立软件的黄昏 AI native Workspace 也许是智能体的下一阶段 科技爱好者周刊(第 381 期):中国 AI 大模型领导者在想什么 科技爱好者周刊(第 380 期):为什么人们拥抱"不对称收益" 科技爱好者周刊(第 379 期):《硅谷钢铁侠》摘录 我如何用 AI 处理历史遗留代码:MiniMax M2.1 升级体验 科技爱好者周刊(第 378 期):预测是新的互联网热点 科技爱好者周刊(第 377 期):14万美元的贫困线 科技爱好者周刊(第 376 期):太空数据中心的争议 科技爱好者周刊(第 375 期):一扇门的 Bug 终于有人做了 Subagent,TRAE 国内版 SOLO 模式来了 科技爱好者周刊(第 374 期):6GHz 的问题 VS Code 使用国产大模型 MiniMax M2 教程 科技爱好者周刊(第 373 期):数据模型是新产品的核心 国产大模型接入 Claude Code 教程:以 Doubao-Seed-Code 为例 科技爱好者周刊(第 372 期):软件界面如何设计 大模型比拼:MiniMax M2 vs GLM 4.6 vs Claude Sonnet 4.5 科技爱好者周刊(第 371 期):一个乐观主义者的专访 科技爱好者周刊(第 370 期):正确的代码高亮 错误处理:异常好于状态码 科技爱好者周刊(第 369 期):Tim 与罗永浩的对谈 科技爱好者周刊(第 368 期):不要这样管理软件团队 一天之内,智谱和 Anthropic 都发了最强编程模型 科技爱好者周刊(第 367 期):Nano Banana 的几个妙用 科技爱好者周刊(第 366 期):旧金山疯狂的 AI 广告 科技爱好者周刊(第 365 期):流量变现正在崩塌 科技爱好者周刊(第 364 期):最难还原的魔方 科技爱好者周刊(第 363 期):最好懂的神经网络解释 科技爱好者周刊(第 362 期):GitHub 工程师谈系统设计 科技爱好者周刊(第 361 期):暗网 Tor 安全吗?
GitHub OAuth 第三方登錄示例教程
阮一峰 · 2019-04-21 · via 阮一峰的网络日志

這組 OAuth 系列教程,第一篇介紹了基本概念,第二篇介紹了獲取令牌的四種方式,今天演示一個實例,如何通過 OAuth 獲取 API 數據。

很多網站登錄時,允許使用第三方網站的身份,這稱為"第三方登錄"。

下面就以 GitHub 為例,寫一個最簡單的應用,演示第三方登錄。

一、第三方登錄的原理

所謂第三方登錄,實質就是 OAuth 授權。用戶想要登錄 A 網站,A 網站讓用戶提供第三方網站的數據,證明自己的身份。獲取第三方網站的身份數據,就需要 OAuth 授權。

舉例來說,A 網站允許 GitHub 登錄,背後就是下面的流程。

  1. A 網站讓用戶跳轉到 GitHub。
  2. GitHub 要求用戶登錄,然後詢問"A 網站要求獲得 xx 權限,你是否同意?"
  3. 用戶同意,GitHub 就會重定向回 A 網站,同時發回一個授權碼。
  4. A 網站使用授權碼,向 GitHub 請求令牌。
  5. GitHub 返回令牌.
  6. A 網站使用令牌,向 GitHub 請求用戶數據。

下面就是這個流程的代碼實現。

二、應用登記

一個應用要求 OAuth 授權,必須先到對方網站登記,讓對方知道是誰在請求。

所以,你要先去 GitHub 登記一下。當然,我已經登記過了,你使用我的登記信息也可以,但為了完整走一遍流程,還是建議大家自己登記。這是免費的。

訪問這個網址,填寫登記表。

應用的名稱隨便填,主頁 URL 填寫http://localhost:8080,跳轉網址填寫 http://localhost:8080/oauth/redirect

提交表單以後,GitHub 應該會返回客戶端 ID(client ID)和客戶端密鑰(client secret),這就是應用的身份識別碼。

三、示例倉庫

我寫了一個代碼倉庫,請將它克隆到本地。


$ git clone [email protected]:ruanyf/node-oauth-demo.git
$ cd node-oauth-demo

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

然後,安裝依賴。


$ npm install

啟動服務。


$ node index.js

瀏覽器訪問http://localhost:8080,就可以看到這個示例了。

四、瀏覽器跳轉 GitHub

示例的首頁很簡單,就是一個鏈接,讓用戶跳轉到 GitHub。

跳轉的 URL 如下。


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

這個 URL 指向 GitHub 的 OAuth 授權網址,帶有兩個參數:client_id告訴 GitHub 誰在請求,redirect_uri是稍後跳轉回來的網址。

用戶點擊到了 GitHub,GitHub 會要求用戶登錄,確保是本人在操作。

五、授權碼

登錄後,GitHub 詢問用戶,該應用正在請求數據,你是否同意授權。

用戶同意授權, GitHub 就會跳轉到redirect_uri指定的跳轉網址,並且帶上授權碼,跳轉回來的 URL 就是下面的樣子。


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

後端收到這個請求以後,就拿到了授權碼(code參數)。

六、後端實現

示例的後端採用 Koa 框架編寫,具體語法請看教程

這裡的關鍵是針對/oauth/redirect的請求,編寫一個路由,完成 OAuth 認證。


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

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

上面代碼中,oauth函數就是路由的處理函數。下面的代碼都寫在這個函數里面。

路由函數的第一件事,是從 URL 取出授權碼。


const requestToken = ctx.request.query.code;

七、令牌

後端使用這個授權碼,向 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需要提供三個參數。

  • client_id:客戶端的 ID
  • client_secret:客戶端的密鑰
  • code:授權碼

作為回應,GitHub 會返回一段 JSON 數據,裡面包含了令牌accessToken


const accessToken = tokenResponse.data.access_token;

八、API 數據

有了令牌以後,就可以向 API 請求數據了。


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,請求的時候必須在 HTTP 頭信息裡面帶上令牌Authorization: token 361507da

然後,就可以拿到用戶數據,得到用戶的身份。


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

(完)