Node.js - Google OAuth2.0
用途
第三方登入使用
- 授權委託,例:google 把使用者的 key 發出去
- 用戶交互的安全協議,但並不是身份認證協議
- 產生 JWT Token 存在 cookie
常見用詞
- Resource Owner 使用第三方登入的使用者,使用者本身
- Client 取的使用者授權的網頁,網頁本身
- Authorization Server 掌管授權的,Resource Owner 使用者確認完後,發放 Grant 授權狀給 client 網頁。 有 Grant 才能取 Token,會回到你指定的 redirect_url
- scope 決定跟使用者要哪些資料,例如:名稱、照片
OAuth2.0 共分 4 種授權類型流程
- Authorization Code Grant Flow (目前的做法)
- Implicit Grant Flow
- Resource Owner Password Credentials Grant Flow
- Client Credentials Grant Flow
如何使用
主要會分成兩隻 API:
- Client 向 Authorization server 發送,其中設置包括 google api console 申請的 client_id、client_secret、redirect_url。
並使用google-auth-library
套件夾帶以上設置
這隻 API 發送的方式會以 form 的方式 post,因爲使用一般發送會跳錯const express = require('express') const router = express.Router() const { OAuth2Client } = require('google-auth-library') const jwt = require('jsonwebtoken') require('dotenv').config() // google 申請的(在 Google developer console) const { GOOGLE_CLIENT_ID, GOOGLE_SECRET_KEY, JWT_SECRET, HOST } = process.env const client = new OAuth2Client({ clientId: GOOGLE_CLIENT_ID, clientSecret: GOOGLE_SECRET_KEY, redirectUri: 'http://127.0.0.1:5173/' // google develooer console 設定的要一樣 })
- 成功取得 client 授權後,解析重新導向回來的 url 中 query 的 code,也就是前一隻設定的 redirect_url 回傳加上的 code
// 回傳路由 router.get('/callback', async (req, res) => { const { code } = req.query try { // 用授權碼換取 token const { tokens } = await client.getToken(code) client.setCredentials(tokens) // 透過 access token 在換取資料 const userInfo = await client.request({ url: 'https://www.googleapis.com/oauth2/v3/userinfo' }) // 創建 JWT const token = jwt.sign(userInfo.data, JWT_SECRET) // 將 JWT 儲存在 Cookie,前端可從 Cookie 中讀取值 res.cookie('token', token) res.redirect('/') // 跳轉回前端頁面 } catch (error) { next(error) } })
還是有看到很多與上面兩個範例兩個不同的做法,可能是套件版本不同
Google API Console 創建自己的 OAuth
[教學] Google OAuth 2.0 申請與使用指南 | 辛比誌
結論
用戶同意授權後,grant 會寫在 redirect_url 上的 query code,發 callback api 取得 token,在向 Authorization Server (google) 發送請求,才會取得用戶的資料。
在 redirect_url 花了很多時間,一開始誤以爲是會傳到網頁上,在去發 callback api,不過看到文章介紹 grant 顯示在 query 不是安全的做法(原本也覺得怪怪的),了解後才發現「 callback 在 Google API Console 就要設定好」。
前端尚未成功,後端扔需努力
參考資料
[筆記] 認識 OAuth 2.0:一次了解各角色、各類型流程的差異
Javascript OAuth2 Google Login & Logout Example Using Access Token in Browser