iT邦幫忙

0

待辦網站Day 25 - 27實作

  • 分享至 

  • xImage
  •  

Day 25 | 環境變數:把密鑰從程式碼裡拿出來
JWT_SECRET目前還寫在程式碼裡,如果推上GitHub,任何人都能偽造token。今天把它移出去。

今天做的事
安裝dotenv,新增.env存放真正的密鑰,另外建一個.env.example放提示文字(這個會上傳,讓別人知道要設定什麼)。config.js改成沒有設定就直接報錯:

require('dotenv').config();

const JWT_SECRET = process.env.JWT_SECRET;
if (!JWT_SECRET) {
  throw new Error('缺少環境變數 JWT_SECRET,請建立 .env 檔案');
}

密鑰用Node內建的crypto產生 64 字元的隨機字串。再用git check-ignore -v .env確認.gitignore真的擋住了它,輸出.gitignore:3:.env就代表成功。最後補上README.md,寫明如何安裝與執行。

觀察

  • 沒有預設密鑰是故意的:萬一正式環境忘了設定,寧可啟動失敗,也不要悄悄用一把公開的預設密鑰
  • .env不上傳、.env.example要上傳,兩者的分工很明確

卡關
我以為重啟伺服器後,之前登入的token會失效,測試卻發現沒有。後來才理解:JWT是無狀態的,伺服器不用記得誰登入過,只要密鑰沒變,簽名就驗得過,重啟並不影響。要讓舊token失效,必須是換掉密鑰。這也呼應了第十九天選JWT的理由:部署在隨時會重啟的主機上,使用者不會頻繁被登出。反過來說,密鑰一旦洩漏,別人就能偽造任何人的token,所以才不能寫進程式碼。

心得
原本以為環境變數只是設定檔,現在知道它其實是在區分可以公開的程式碼跟不能公開的秘密。

Day 26 | 整體測試:把自己當成第一個使用者
不寫新功能,把註冊、登入、新增、編輯、完成、刪除、篩選、搜尋、兩個帳號隔離,全部照清單跑一遍。

今天做的事
列出測試表逐項確認,並特別測試幾個邊界狀況:重複註冊、錯誤密碼、空白標題、壞掉的JSON、登出後的行為。

觀察

  • 登出後按瀏覽器'上一頁',畫面還是顯示剛才的清單,要重新整理才會被導回登入頁。這是因為瀏覽器會把整個頁面快取起來還原,JavaScript並沒有重新執行,所以沒有發出請求。真正的保護在後端:畫面只是舊的快照,一旦點擊操作,沒有token的請求就會被拒絕
  • 前端用textContent顯示標題,所以就算標題寫成HTML標籤,也只會原樣顯示成文字

卡關
測試時發現無法新增待辦事項。打開Network分頁,POST /api/todos 回傳404,內容是JSON 格式的API 路徑不存在。Express自己的404是一整頁HTML,這個JSON是我在server.js 最後寫的兜底路由回應的,代表這個請求跑完所有路由都沒有對上。我用同一個方法排查:看Network的狀態碼和回應內容、檢查server.js的路由順序、確認有沒有舊的伺服器程序占著port。

心得
這次學到最有用的一件事是看回應的格式也能判斷是誰回的:HTML是框架自己的,JSON是我自己寫的。測試不是為了證明沒問題,而是為了找出沒想到的問題。

Day 27 | 部署前準備:PORT、start 指令與健康檢查
網站在自己電腦上跑得好好的,丟到雲端之前要先改幾個地方。

今天做的事

  • 連接埠改成讀環境變數:雲端平台會指定port,不能寫死 3000
  • package.json新增start指令,平台才知道怎麼啟動
  • 加上/health路由,用來確認服務有沒有活著
  • 加上trust proxy
app.set('trust proxy', 1);
const PORT = process.env.PORT || 3000;
app.get('/health', (req, res) => res.json({ status: 'ok' }));

資料庫路徑也改成可以用DB_PATH環境變數指定。

觀察

  • 部署在雲端時,請求會先經過代理伺服器,如果沒有設定trust proxy,限流看到的永遠是代理的IP,等於所有人共用同一個額度
  • 改用npm start啟動,確認功能跟之前完全一樣,這個動作很重要:部署前先在本機用同樣的方式啟動一次
  • 上傳前用git status確認沒有 .env、todos.db、node_modules

心得
在我的電腦上能跑跟在別人的電腦上能跑中間,隔著一堆平常看不見的假設,例如port、環境變數、啟動方式。今天就是一項一項把這些假設變成設定。


圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言