---
title: "使用 NestJS - 實作第三方 OAuth 授權登入服務"
description: "用 NestJS 搭配 Prisma、JWT 與 Swagger 實作完整的 OAuth 2.0 授權碼模式服務，並以 Next.js 電商網站為前端示範整合流程。"
canonical_url: "https://blog.markkulab.net/post/practice-oauth-with-nestjs"
author: "Mark Ku"
author_url: "https://blog.markkulab.net/author/mark-ku"
site: "Mark Ku's Blog"
date_published: "2024-10-14 01:01:35 +0800"
category: "Backend"
tags: ["nestjs", "oauth", "jwt", "prisma", "nodejs", "backend", "authentication"]
language: "zh-TW"
license: "CC BY 4.0"
license_url: "https://creativecommons.org/licenses/by/4.0/"
attribution: "轉載或引用請註明作者並附上原文連結"
---

# 使用 NestJS - 實作第三方 OAuth 授權登入服務

## 前言
做了簡易的 OAuth 練習，就順便學了 NestJS (Node)後端框及 Prisma (ORM) 。

## 目的
開放授權（OAuth）是一個開放授權標準，廣泛用於社群授權登入，讓第三方網站可以不用取得使用者帳密，就能存取資源服務器資源。

## 流程圖
![Flow chart](https://blog.markkulab.net/content/markku/posts/practice-oauth-with-nestjs/images/flow-chart.png)

## 流程說明
1.在主網站按下登入按鈕，會透過 URL 將 redirect_uri 傳遞至 OAuth 登入頁面。  
2.使用者輸入帳號密碼完成登入後，系統會產生一個 code，並將其存入資料庫，然後將頁面重定向回電商網站的 callback 頁面，並將 code 透過 URL 傳遞過去。  
3.在 callback 頁面，前端可以從 URL 中獲取 code，並將其傳送至後端，透過 OAuth API 使用該 code 換取 access token。  
4.頁面會取得到的 access token，此時可以使用該 access token 去訪問資源伺服器，取得相關資訊，過期時則可以去換token。  

## 此次採用的技術架構是
* 前端(電商網站) - (Next.JS、Eslint、Pritter、React、Redux toolkit) - [程式碼](https://github.com/markku636/oauth.nextjs)
* 後端(OAuth 服務) -( Nest JS、Mysql、Prisma 、 Swagger 、 class-validator做資料驗證、並用Guard 做JWT的API驗證) - [程式碼](https://github.com/markku636/oauth.nest.api)
* 資料庫 MYsql

## Demo 
* [EC site](https://oauth-nextjs.letgo.com.tw)
* [Auth service api](https://oauth-nestjs-api.letgo.com.tw)
* [Swagger Url](https://oauth-nestjs-api.letgo.com.tw/docs) -  admin / 123
* [Demo影片](https://www.loom.com/share/fdac0b89ace64bc3b3ad5a85098d0499)

佈署環境
* 使用Powerhsell 佈署到Nas 
* GCP 反向代理 + 個人 Nas 伺服器

測試
* Jest
* Rest Clinet 

## 心得 
這是我第一次使用 NestJS 撰寫網站，發現它的開發體驗非常友好，NestJS 的模組化設計讓我聯想到 Angular 的依賴注入方式，同時也有點像 .NET MVC 的分層結構，搭配 Prisma，資料庫操作變得非常直觀，對於輕量型網站，NestJS 不僅開發速度快，還能輕鬆實現模組化和關注點分離，讓開發過程更加高效。

## 補充: 
### 1. OAuth 有好幾種模式 (type) ，順便整理一下
* 授權碼模式 Code - 在這種模式下，授權碼用於交換訪問令牌，應用程式不會直接接觸到用戶帳密。
* 憑證式(Client Credentials Grant) - 客戶端憑證模式， 服務A想訪問服務B的API，服務A使用自己的客戶端憑證(服務B發放的)獲取訪問令牌。
* 隱藏式(Implicit Grant)  -  透過 Javascript ，但因為安全性問題逐漸被廢棄。
* 密码式(Resource Owner Password Credentials Grant) - :直接和用戶端要帳密，安全性較低現在比較沒在用。
### 2. OAuth 和 SSO的差異
* SSO：SSO 的目的是簡化多個應用程式之間的用戶登入流程，讓用戶只需一次登入，即可在多個應用程式中無縫使用同一個身份。SSO 主要專注於 身份驗證，即確認用戶是誰。
* OAuth：OAuth 則是一種授權協定，允許第三方應用程式代表用戶訪問受保護的資源，OAuth 的主要目的是 授權，讓應用程式能夠安全地獲取用戶的某些資源，而不需要直接存取用戶的憑證（如密碼）。

### 3. 新的議題，OpenID Connect (OIDC)
* OpenID Connect :是基於 OAuth 2.0 的身份驗證層，專門用於身份驗證並支援 SSO ，OIDC 是 SSO 和 OAuth 的一個混合應用，它同時解決了身份驗證和授權的需求。

### 4. 什麼是認證，什麼是授權
* 認證 - 你是誰? 識別來源身份是否有效
* 授權 - 目標的用戶能做什麼 ? 或能訪問什麼 ?

## 參考
* [參考資料1](https://docs.guandata.com/article/1/566167986377850880.html)
* [參考資料2](https://apifox.com/help/best-practices/how-to-test-oauth-2.0/)
* [參考資料3](https://www.youtube.com/watch?v=2rd_Ru7Bwkg&t=386s)
* [官方文件](https://oauth.net/2/)

---

## 關於本文與作者

本文出自 [Mark Ku's Blog](https://blog.markkulab.net/post/practice-oauth-with-nestjs)

授權條款： [CC BY 4.0](https://creativecommons.org/licenses/by/4.0/) — 轉載或引用請註明作者並附上原文連結

### 關於作者

**[Mark Ku](https://blog.markkulab.net/author/mark-ku)** — Software Solution Provider

- 10+ 年資深軟體工程師，現為 AI 應用 Builder
- 專注大型平台架構設計，從北美電商到AI SaaS訂閱收費系統
- 結合 AI Agent 與自動化，打造高效可演進的產品技術基礎

### 作者開發的免費工具

以下工具皆可免費使用：

- [免費 PDF 簽名工具](https://blog.markkulab.net/tools/pdf-sign): 線上 PDF 簽名工具，瀏覽器內完成手繪、打字、上傳簽名，可拖曳放置、縮放、下載。所有處理都在你的裝置完成，檔案不會上傳。
- [VS Code Refactory](https://blog.markkulab.net/tools/refactory): Refactory 是一款 VS Code 重構擴充套件：34 個重構動作、37 條 code smell 檢查、Code Health 儀表板、18 種語言、534 支測試。懂你的專案慣例：介面放哪、DI 註冊寫在哪、'use client' 該不該加；還會用 git 修改頻率 × 複雜度排出「該先修哪個檔案」，並一鍵把壞味道交給你自己電腦上的 Claude Code 修。免費使用，原始碼不離開你的機器。
- [DB-Kit 資料庫管理工具](https://blog.markkulab.net/tools/db-kit): DB-Kit 是一個用 Tauri + Rust + React 打造的輕量跨平台資料庫管理工具，用單一一致的介面同時管理 MySQL、MariaDB、PostgreSQL、SQL Server、Oracle、SQLite、MongoDB、Redis、Kafka、Elasticsearch 與 RabbitMQ 十一種資料來源：連線密碼以 OS keychain 加密、SSH Tunnel、完整 CRUD、視覺化查詢建構器、多結果集同時顯示、跨連線資料傳輸與比對同步、Excel / CSV 匯入匯出、執行計畫視覺化、ER 圖、排程備份、SQL 壓力測試（p50～p99 延遲百分位）、15 條規則的 SQL 審查、Kafka 訊息瀏覽與監控告警；繁中 / 英文雙語介面，內建 AI 助手（自然語言生成 SQL、AI 審查與調校建議）與命令列工具 dbk。免費開源（MIT），提供 Windows / macOS / Linux 安裝檔。
- [VS Code Super Mermaid](https://blog.markkulab.net/tools/super-mermaid): Super Mermaid 是一款 VS Code 擴充套件：開箱即用的漂亮 Mermaid 圖表，自動上色、即時預覽、滑鼠平移縮放、PNG / SVG 高解析匯出，內建 21 種範本與多種主題。免費開源（MIT）。
- [React Super Mermaid](https://blog.markkulab.net/tools/react-super-mermaid): react-super-mermaid 是一個開源 React 元件庫：一行 <MermaidViewer> 即可渲染漂亮的 Mermaid 圖表，內建 colorful / sketch 主題、平移縮放、圖內搜尋、SVG / PNG 高解析匯出。輕量、SSR 安全、完整 TypeScript 型別。免費開源（MIT）。
- [Jira / Confluence Super Mermaid](https://blog.markkulab.net/tools/jira-super-mermaid): Atlassian Forge app：在 Jira issue 與 Confluence 內文直接寫 Mermaid 語法，畫流程圖、時序圖、狀態機與甘特圖。11 種圖表、SVG / PNG 匯出、明暗主題、完整中日韓文字支援。取得 Runs on Atlassian 資格：圖表存在你自己的站台，app 不呼叫任何第三方服務。免費，即將上架 Atlassian Marketplace。
- [Mermaid 線上預覽](https://blog.markkulab.net/tools/mermaid-preview): 在瀏覽器裡寫 Mermaid、即時看圖，整張圖表壓進網址就能分享。免註冊、不上傳伺服器，相容 mermaid.live 的分享連結。
- [React Intl Phone Number](https://blog.markkulab.net/tools/react-intl-phone-number): react-intl-phone-number 是一個開源 React 元件：framework-agnostic、不依賴 antd，提供 E.164 進出、可搜尋國旗 / 國碼下拉、可配置驗證等級（strict / mobile-strict / loose）、可主題化 CSS 與 i18n，電話邏輯由 google-libphonenumber 驅動。輕量、完整 TypeScript 型別。免費開源（MIT）。
- [Uptime Kuma Cluster](https://blog.markkulab.net/tools/uptime-kuma-cluster): 把單機版 Uptime Kuma 改造成高可用叢集：OpenResty + Lua 智慧負載平衡、MariaDB 共享狀態、健康檢查與自動 Failover，附叢集管理 REST API，一行 Docker Compose 啟動。免費開源（MIT）。
- [特教專案](https://blog.markkulab.net/education): 為特殊教育學生製作的學習教材

### 每日 Podcast

- [科技新鮮事](https://blog.markkulab.net/category/tech-news): 每日精選 AI 與科技趨勢，透過語音摘要快速掌握最新技術動態，涵蓋 AI 應用、軟體架構、DevOps 與工程實戰。 — RSS: https://blog.markkulab.net/feed.xml
- [AI股市蝦聊](https://blog.markkulab.net/category/ai-stock-chat): 每個交易日用 AI 分析台股盤勢，以雙人對話聊當天的盤中觀察與隔日預測。 — RSS: https://blog.markkulab.net/ai-stock-chat/feed.xml

### 電子報

[訂閱電子報](https://blog.markkulab.net/subscribe) — 第一時間收到新文章通知，無垃圾信、隨時可取消訂閱。
