第三方程式串接 (API Key 管理)
配發 API Key 與 Secret 給旅館 PMS 系統,供其換取 JWT Token 以控制硬體。
| ID | 合作夥伴名稱 | API Key (Client ID) | 建立時間 | 到期時間 (授權期限) | 狀態 | 操作 |
|---|---|---|---|---|---|---|
| {{ partner.id }} | {{ partner.name }} | {{ partner.api_key }} |
{{ new Date(partner.created_at).toLocaleString('zh-TW', { year: 'numeric', month: 'numeric', day: 'numeric' }) }} |
{{ partner.expires_at ? new Date(partner.expires_at).toLocaleString('zh-TW', { year: 'numeric', month: 'numeric', day: 'numeric' }) : '無期限' }}
|
{{ partner.is_active && !isExpired(partner.expires_at) ? '啟用中' : '已過期/停用' }} | |
| 目前沒有任何合作夥伴紀錄 | ||||||
API 串接測試文件 - PMS 發卡
提供給第三方廠商的發卡硬體控制標準介接說明。
PMS MQTT 橋接 API 文件
📌 串接前置說明 (Integration Guide)
範例:
https://您的主機網域.com
👉 以「取得存取權杖」為例,完整網址為:
https://您的主機網域.com/api/auth/token
- 取得金鑰: 請先於合作夥伴管理列表,由管理員建立並配發一組專屬的
API Key與API Secret。 - 換取 Token: 依照下方【第 1 步】,使用這組金鑰換取 1 小時效期的
Access Token。 - 發送指令: 依照下方【第 2 步】,在 Request Header 中帶入
Bearer <Token>即可成功傳遞硬體控制資料。
1. 取得存取權杖 (Get Access Token)
在呼叫任何硬體控制 API 之前,必須先使用您的
API Key 與 API Secret 換取 1 小時效期的 JWT Token。
Request Body (application/json)
{
"api_key": "pk_160035...",
"api_secret": "sk_9f1c8a..."
}
Response
{
"access_token": "eyJhbGciOiJIUzI1NiIsIn...",
"token_type": "Bearer",
"expires_in": 3600
}
2. 發送硬體指令 (Publish Command)
使用取得的 Token 來發送控制指令給指定硬體設備。
Headers
Authorization: Bearer <您的_ACCESS_TOKEN>
Content-Type: application/json
Request Body (application/json)
{
"data": "置入取得的虛擬金鑰Vkey"
}
Response (成功)
{
"status": "success"
}
系統架構說明
PMS MQTT 橋接系統的完整資料流與元件架構圖。
PMS MQTT 橋接系統架構
📋 架構總覽
本系統透過 AWS 雲端服務實現 雙向 MQTT 通訊,讓第三方 PMS 廠商能安全地控制旅館硬體設備(如門鎖、發卡機)。
系統包含 下行控制(雲端→設備)與 上行回報(設備→雲端)兩條資料流路徑。
🧩 系統元件說明
| 元件 | 技術 | 說明 |
|---|---|---|
| PMS_MQTT 前端 | Vue 3 + Firebase |
環境監控儀表板,提供即時數據顯示、MQTT 指令發佈、系統日誌 |
| PMS API Manager | Express + SQLite + JWT |
廠商金鑰管理、JWT 認證、API 文件入口 (本系統) |
| AWS API Gateway | HTTP API |
接收前端 HTTP POST 請求,觸發 Lambda 函數 |
| PublishToMQTT | Lambda (Node.js 24.x) |
將 HTTP 請求轉換為 MQTT 訊息,發佈至 AWS IoT Core |
| AWS IoT Core | MQTT Broker |
雲端 MQTT 中樞,負責訊息路由與設備通訊 |
| IoT-To-Firestore | Lambda (Node.js 20.x) |
接收設備 MQTT 回報,寫入 Firebase Firestore 供前端即時更新 |
| Firebase Firestore | NoSQL 即時資料庫 |
儲存設備狀態與歷史紀錄,透過 onSnapshot 推播即時更新 |
📊 資料流架構圖
app.js
POST JSON
us-east-1
觸發
PublishToMQTT
MQTT Publish
MQTT Broker
訂閱接收
門鎖/發卡機
狀態回報
MQTT Publish
MQTT Broker
Rule 觸發
IoT-To-Firestore
寫入
即時資料庫
onSnapshot
即時更新 UI
🖥️ 本地服務對照表
| 服務 | Port | 專案 | 說明 |
|---|---|---|---|
| API Manager | localhost:3000 |
PMS_API_Manager | 後端核心 — 廠商管理、JWT 認證、硬體指令轉發 |
| Swagger Docs | localhost:4000 |
PMS_API_Docs | 互動式 API 文件 — 供開發者線上試打 API |
| MQTT Dashboard | localhost:8080 |
PMS_MQTT | 環境監控前端 — 即時數據、指令發佈、日誌 |
🔐 安全認證機制
- 管理員在 合作夥伴管理 頁面建立廠商,系統自動配發
API Key+API Secret - API Secret 經 SHA-256 雜湊 後儲存,原始值僅在建立時顯示一次
- 第三方使用 Key + Secret 呼叫
/api/auth/token換取 JWT Token(效期 1 小時) - 後續所有硬體控制 API 需在 Header 攜帶
Bearer Token,由 verifyToken 中介軟體 驗證 - Token 過期或廠商授權到期,系統自動拒絕存取(
403 Forbidden)
金流與擴充架構
未來第三方金流整合與 API Manager 自動化授權架構規劃。
為何金流不該分拆為獨立伺服器?
在商業架構中,強烈建議將「金流串接」與現有的「API Manager」整併在同一個伺服器 (Node.js) 中運行。
由於 API Key 與過期時間 (Expiry Date) 的資料庫 都存放在此 API Manager 內,若將金流系統獨立為另一台伺服器,將會大幅增加兩台伺服器互相通訊失敗的風險(例如客戶已付款,但金流伺服器跨網域通知 API Manager 失敗,導致客戶權限未開通,產生客服爭議)。
🔄 自動化金流運作流程 (SaaS 訂閱模式)
- 廠商發起付款: 廠商登入本儀表板,點擊「續約 / 購買方案」,系統引導至第三方支付 (如 ECPay 綠界, Stripe, 藍新) 刷卡頁面。
- 背景接收回呼 (Webhook): 廠商付款成功後,第三方支付會在背景發送一筆「成功付款通知 (Webhook POST)」給您的 API Manager 伺服器 (
/api/payment/webhook)。 - 自動展延授權: API Manager 接收並驗證 Webhook 的檢查碼後,直接執行資料庫更新:
UPDATE partners SET expiry_date = '+1 year' WHERE id = ? - 無縫恢復連線: 廠商的 API Key 瞬間恢復效力,自動取得全新的 JWT Token,無須人工介入即可繼續發送指令至 AWS。
🏗️ 未來金流整合系統架構圖
第三方廠商
(在儀表板操作續約)第三方支付網關
(ECPay / Stripe / 藍新)SQLite 資料庫
(金鑰與過期時間)PMS API Manager
(整合金流與驗證的核心)AWS 雲端
(API Gateway + IoT)部署與更新教學
交接文件:如何更新 AWS EC2 雲端伺服器的程式碼與架構資訊
📦 一鍵自動更新流程 (推薦)
為了方便交接與後續維護,系統已內建自動化部署腳本。未來若您在本地端 (Local) 修改了任何 PMS_API_Manager 的程式碼,只需透過以下步驟即可一鍵將更新推送到 AWS EC2 正式環境:
更新三部曲
- 打開您的 Mac 終端機 (Terminal)。
- 切換目錄到專案資料夾:
cd ~/Desktop/PMS_API_Manager - 執行自動化部署腳本:
./deploy.sh
deploy.sh 會自動透過 rsync 將您本地端的最新程式碼傳送到 EC2,並且 自動避開 data/pms.db 資料庫檔案(避免覆蓋雲端的正式廠商資料)。最後會透過 SSH 自動遠端執行 pm2 restart pms-api,讓新程式碼立即生效。
☁️ 雲端伺服器 (EC2) 規格與連線資訊
- 公網 IP 位址 (BASE URL):
http://3.27.15.192:3000 - SSH 連線使用者:
ubuntu - SSH 金鑰路徑 (本地):
~/AWS_Key/pms-api-key.pem - 專案存放路徑 (EC2):
~/PMS_API_Manager - 背景常駐工具:
PM2(進程名稱為pms-api)
手動連線至主機 (進階)
若需要手動進去主機查看日誌或除錯,請使用以下指令連線:
ssh -i ~/AWS_Key/pms-api-key.pem ubuntu@3.27.15.192
查看 PM2 即時運行日誌:
pm2 logs pms-api
AWS EC2 多應用部署架構
單一主機透過 Nginx 反向代理,以路徑節點掛載多個獨立應用服務。
架構設計理念
💡 為什麼用一台 EC2?
使用一台 EC2 搭配 Nginx 反向代理是目前最經濟且靈活的方案。
一個固定 IP (3.27.15.192),
可以透過「路徑節點」掛載無限多個應用,各應用之間完全獨立、互不干擾。
未來若流量增長,可隨時拆分為獨立主機或升級為 Load Balancer 架構。
📊 流量分流架構圖
PM2 → Port 3000靜態檔案服務PM2 → Port 8899靜態檔案服務📋 應用服務對照表
| 專案名稱 | 類型 | 部署方式 | URL 路徑 | 狀態 |
|---|---|---|---|---|
| PMS API Manager | Node.js API | PM2 (Port 3000) |
/pms/ |
運行中 |
| Vsitth 訪客管理 | 靜態前端 + Firebase | Nginx 靜態服務 |
/vsitth/ |
運行中 |
| Meeting System | 靜態前端 + Firebase | Nginx 靜態服務 |
/meeting/ |
運行中 |
| AI Cube 健康監測 | 靜態前端 | Nginx 靜態服務 |
/aicube/ |
運行中 |
| Blockchain Test | 靜態前端 | Nginx 靜態服務 |
/blockchain/ |
運行中 |
| 採購分析物料成本 | Node.js + SQLite | PM2 (Port 8899) |
/bom/ |
規劃中 |
🖥️ EC2 主機資訊
🧭 架構決策:一台 EC2 還是多台?
目前開發方向分為兩大類,性質不同但共用同一台 EC2:
| 🔌 API 串接管理 | 🖥️ 前後端應用開發 | |
|---|---|---|
| 代表專案 | PMS API Manager | Vsitth、BOM 採購分析、Meeting System |
| 性質 | 對外開放的 API 閘道,第三方廠商會打進來 | 內部/自用工具,瀏覽器直接操作 |
| 安全等級 | 🔴 較高 (JWT、API Key、廠商機密) | 🟢 一般 (Firebase Auth 驗證) |
| 流量來源 | 機器對機器 (M2M),24/7 自動化 | 人為操作,上班時間為主 |
✅ 現階段結論:使用一台 EC2 + Nginx 子路徑
- 成本最優:一台 EC2 (t3.micro) 約 $8-10 USD/月,兩台則翻倍
- 維護集中:一個地方做安全更新、看 Log、管理 SSH Key
- 隔離足夠:各應用跑在獨立 PM2 進程,互不影響。Nginx 路徑分流本身即邏輯隔離
- 天然支持擴展:未來若要拆分,只需把 Nginx 的 proxy_pass 指向新 IP,零改動
⚡ 什麼時候該拆成兩台 EC2?
| 觸發條件 | 說明 |
|---|---|
| 合作廠商數量 > 10+ | API 流量開始影響前端應用的回應速度 |
| 客戶要求安全合規 | 例如 ISO 27001 要求生產 API 與內部工具實體隔離 |
| 團隊分工需求 | 不同人負責不同系統,需要獨立部署權限與 SSH Key |
| 服務可用性 SLA | API 需保證 99.9% 不中斷,不能因為前端部署而 reload |
Nginx 反向代理設定
EC2 上的 Nginx 設定檔範本與部署指令備忘錄。
Nginx 設定檔範本
📄 /etc/nginx/sites-available/multi-app
server {
listen 80;
server_name 3.27.15.192;
# ─── PMS API Manager (Node.js via PM2) ───
location /pms/ {
proxy_pass http://127.0.0.1:3000/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
# ─── Vsitth 訪客管理系統 (靜態前端) ───
location /vsitth/ {
alias /var/www/vsitth/;
try_files $uri $uri/ /vsitth/index.html;
}
# ─── 未來: 採購分析系統 (Node.js via PM2) ───
# location /bom/ {
# proxy_pass http://127.0.0.1:8899/;
# }
# ─── 預設首頁 ───
location / {
return 301 /pms/;
}
}
🔧 部署指令備忘
🚀 Vsitth 部署腳本 (本機端執行)
testVsit/Vsitth/ 專案目錄中,執行 vite build 後,
使用 rsync 將 dist/ 資料夾同步至 EC2 的 /var/www/vsitth/。
#!/bin/bash
# deploy-vsitth.sh
echo "=========================================="
echo "🚀 部署 Vsitth 訪客管理系統至 AWS EC2"
echo "=========================================="
# 1. Build
echo "📦 正在執行 Vite Build..."
npm run build
# 2. Upload
echo "📤 正在同步至 EC2..."
rsync -avz --delete \
-e "ssh -i ~/AWS_Key/pms-api-key.pem" \
dist/ ubuntu@3.27.15.192:/var/www/vsitth/
# 3. Reload Nginx
echo "🔄 重新載入 Nginx..."
ssh -i ~/AWS_Key/pms-api-key.pem ubuntu@3.27.15.192 \
"sudo systemctl reload nginx"
echo "=========================================="
echo "✅ 部署完成!"
echo "🌐 https://3.27.15.192/vsitth/"
echo "=========================================="
⚠️ 重要注意事項
部署至 EC2 後,必須在 Firebase Console → Authentication → Settings → Authorized domains 中, 將
3.27.15.192 加入授權清單,否則 Firebase Auth 登入功能會被阻擋。
若購買了域名 (例如
vsitth.thinkpos.com),可改用子域名搭配
Let's Encrypt 免費 SSL 憑證,輕鬆升級為 HTTPS 安全連線。