
HapiJS 身份驗證 : 使用 JWT 保護(hù)您的 API
以 AI Proxy 應(yīng)用為例,這是一個典型的前后端分離架構(gòu)的應(yīng)用,主要由兩部分組成:
接下來,我將詳細(xì)介紹如何高效地開發(fā)這樣一個生產(chǎn)級別的系統(tǒng)。
首先在 Sealos Cloud (https://hzh.sealos.run) 中打開 Debox 應(yīng)用,創(chuàng)建一個新項目,選擇 Go 作為運行環(huán)境,選擇 1.23 版本。
Devbox 為開發(fā)者提供了幾個非常實用的功能:
創(chuàng)建完成后,幾秒鐘即可啟動開發(fā)環(huán)境。
環(huán)境準(zhǔn)備好后,我們直接用 Cursor 連接開發(fā)環(huán)境。在操作選項中選擇使用 Cursor 連接:
首次打開會提示安裝 Devbox 插件,安裝后即可自動連接開發(fā)環(huán)境。
首先 Fork Sealos 源碼到自己的倉庫,然后再將你自己的倉庫克隆到 Devbox 開發(fā)環(huán)境:
在 Cursor 的面板中切換到 “Databse” 標(biāo)簽頁,然后點擊箭頭指向的按鈕,在瀏覽器中打開 Sealos 的數(shù)據(jù)庫應(yīng)用:
然后創(chuàng)建 PostgreSQL 和 Redis 實例。
回到 Cursor 面板的 “Database” 標(biāo)簽頁,點擊刷新即可看到剛創(chuàng)建的數(shù)據(jù)庫實例,點擊可復(fù)制連接信息:
在終端中啟動服務(wù):
export ADMIN_KEY=sealos-admin
export SQL_DSN=<復(fù)制的pgsql連接串>/postgres
export REDIS_CONN_STRING=<復(fù)制的redis連接串>
go run . --port 8080
提示 server stared
即為啟動成功
在 Cursor 面板的 “Network” 標(biāo)簽頁中,點擊地址欄右側(cè)的 ?? 按鈕,然后在彈窗中選擇 “Copy”,將地址復(fù)制到自己電腦上使用 curl 進(jìn)行測試:
curl https://mmznjndvzdrv.sealoshzh.site/api/status -H "Authorization: sealos-admin"
接口返回沒有問題。
在開發(fā)過程中,我們發(fā)現(xiàn)數(shù)據(jù)庫中 Group 和 Token 之間的外鍵約束增加了系統(tǒng)維護(hù)的復(fù)雜度。為了簡化這一關(guān)系,我們可以將外鍵約束改為程序?qū)用娴娘@式調(diào)用,這樣可以讓代碼邏輯更加清晰和可控。
首先切換到 fix-aiproxy
分支:
在 sealos/service/aiproxy/model/group.go
文件中,我們需要將 Group 結(jié)構(gòu)體中一個外鍵約束改成在程序內(nèi)顯示調(diào)用更新和刪除來降低維護(hù)心智。
這里我選擇使用 Cursor 的 Chat 功能讓 AI 自己寫代碼,最后生成的結(jié)果如下:
這種實現(xiàn)方式的優(yōu)勢在于:當(dāng)刪除 Group 時,相關(guān)的 Token 刪除操作會在同一個事務(wù)中完成。由于是在事務(wù)內(nèi)進(jìn)行,我們不需要擔(dān)心刪除失敗或系統(tǒng)宕機(jī)導(dǎo)致的數(shù)據(jù)不一致問題。
我們可以通過一系列測試來驗證這個優(yōu)化是否達(dá)到預(yù)期效果。首先編譯并運行服務(wù):
go build . && ./aiproxy --port 8080
然后通過以下 API 調(diào)用來測試完整的 Group 和 Token 生命周期:
# 創(chuàng)建一個group
curl https://gawavirgsomu.sealosbja.site/api/group/ -H "Authorization: sealos-admin" -d '{
"id": "ns-admin"
}'
# 創(chuàng)建一個token
curl https://gawavirgsomu.sealosbja.site/api/token/ns-admin -H "Authorization: sealos-admin" -d '{
"name": "token 1"
}'
# 查詢token
curl https://gawavirgsomu.sealosbja.site/api/tokens/ -H "Authorization: sealos-admin"
# 刪除group
curl https://gawavirgsomu.sealosbja.site/api/group/ns-admin -H "Authorization: sealos-admin" -X DELETE
# 再次查詢token
curl https://gawavirgsomu.sealosbja.site/api/tokens/ -H "Authorization: sealos-admin"
測試結(jié)果符合預(yù)期,確認(rèn)優(yōu)化方案可行。接下來我們就可以提交這些更改并創(chuàng)建 Pull Request 了。
首先在 Cursor 目錄頂層的 endpoint.sh 中設(shè)置啟動命令,在文件中添加以下啟動配置:
cd sealos/service/aiproxy
export ADMIN_KEY=sealos-admin
# 可以再創(chuàng)建一個單獨的生產(chǎn)環(huán)境數(shù)據(jù)庫,與開發(fā)環(huán)境隔離
export SQL_DSN=<復(fù)制的pgsql連接串>/postgres
export REDIS_CONN_STRING=<復(fù)制的redis連接串>
# 使用編譯好的二進(jìn)制文件
./aiproxy --port 8080
然后來到 Devbox 發(fā)布頁面發(fā)布版本:
點擊發(fā)布按鈕后,等待發(fā)布流程完成。發(fā)布成功后,點擊 “上線” 按鈕進(jìn)入部署頁面,然后點擊 “部署應(yīng)用” 即可:
部署完成后,進(jìn)入應(yīng)用的詳情頁面,等待應(yīng)用變成 running 狀態(tài),然后復(fù)制公網(wǎng)地址:
這個公網(wǎng)地址就是生產(chǎn)環(huán)境的域名,我們可以使用生產(chǎn)環(huán)境的域名進(jìn)行測試:
# 這里使用的是生產(chǎn)環(huán)境的域名
curl https://jpesudzryuhp.sealosbja.site/api/tokens/ -H "Authorization: sealos-admin"
前端環(huán)境的搭建與后端類似,具體步驟如下:
4c 16G
的配置。然后克隆你自己 Fork 的 Sealos 倉庫:git clone https://github.com/xxx/sealos.git
。AI Proxy 的前端代碼位于 sealos/frontend/providers/aiproxy
目錄。sealos/frontend
目錄,首先修改 sealos/frontend/package.josn
文件,去除 node 版本限制,直接刪除 "node": "20.4.0"
和 "pnpm": "8.9.0"
這兩行即可,這一步很重要,不然代碼構(gòu)建依賴會不成功。pnpm i
安裝依賴。pnpm -r --filter ./packages/client-sdk run build
構(gòu)建 client-sdk 包。sealos/frontend/providers/aiproxy
:切換目錄后,建議安裝所有 @recommended 插件以獲得最佳的開發(fā)體驗:
sealos/frontend/providers/aiproxy
進(jìn)行安裝。直接執(zhí)行命令 pnpm i
安裝即可:項目搭建完成后,我們需要配置環(huán)境變量來對接后端服務(wù)。在項目根目錄創(chuàng)建一個 .env
文件,需要配置以下幾個關(guān)鍵變量:
NEXT_PUBLIC_MOCK_USER=""
AI_PROXY_BACKEND_KEY=""
APP_TOKEN_JWT_KEY="test123"
AI_PROXY_BACKEND=""
AI_PROXY_BACKEND_INTERNAL=""
ADMIN_NAMESPACES=""
NEXT_PUBLIC_MOCK_USER
:由于 AI Proxy 是 Sealos Desktop 的一部分,用戶認(rèn)證通過 JWT Token 實現(xiàn),AI Proxy 只做解析 Token,JWT Token 的簽發(fā)由 Sealos Desktop 完成。在開發(fā)階段,我們需要 mock 一個 JWT Token。NEXT_PUBLIC_MOCK_USER 的值就是 mock 出來的 JWT Token。可以使用在線工具 https://www.lddgo.net/encrypt/jwt-generate 生成。mock 數(shù)據(jù)如下:
{
"workspaceId" : "test"
}
APP_TOKEN_JWT_KEY
:JWT Token 的密鑰 (隨便寫)AI_PROXY_BACKEND_KEY
:后端 API 的訪問密鑰 (也就是后端項目的 ADMIN_KEY)AI_PROXY_BACKEND
:后端服務(wù)的公網(wǎng)地址AI_PROXY_BACKEND_INTERNAL
:后端服務(wù)的內(nèi)網(wǎng)地址 (開發(fā)測試階段可以不填)ADMIN_NAMESPACES
:管理員用戶名,開發(fā)時填 test 就行,和 token 中的 “workspaceId”:“test” 保持一致環(huán)境變量配置完成后,運行 pnpm dev
即可啟動開發(fā)服務(wù)器。項目的發(fā)布和部署流程與前面介紹的后端開發(fā)流程完全一致。
AI Proxy 前端項目采用了經(jīng)典的 Next.js App Router 架構(gòu),其中 app/[lng]
目錄用于頁面路由,app/api
目錄則用于后端 API 路由。
在這個項目中,Next.js 的后端實際上是一個中間層,它主要負(fù)責(zé)用戶認(rèn)證相關(guān)的業(yè)務(wù)邏輯,并將經(jīng)過認(rèn)證的請求轉(zhuǎn)發(fā)給真正的 Golang 后端服務(wù)。這種分層設(shè)計可以讓 Golang 后端專注于核心業(yè)務(wù)邏輯,不需要關(guān)心認(rèn)證等基礎(chǔ)設(shè)施,從而提高了代碼的靈活性和可移植性。
本文轉(zhuǎn)載自公眾號@sealos