前端藏不了任何東西

前言

最近更新公司的網站,除了 UI 以外也改了架構上的東西
專案不僅要分成 testnet, staging, mainnet 三種環境
在每個環境下又要支援不同鏈的切換,進而顯示不同內容

專案中還放一個策略設定檔,用來顯示該鏈所有策略的資料
這個設定檔的特別之處在於不能納入 build
因為希望之後等網站部署好,其他人(例如marketing)能夠藉由別的方式去修改server上的設定檔
這樣未來無論我們新增了多少策略,都不需要透過前端我更新網頁,也不需要重跑CICD的流程
以達到前端的最終型態

public 資料夾

public 資料夾是 react 專案中特別的存在
在不做其他額外設定之下
裡面的檔案不會經過 compile, 而是在 build 之後被原封不動地放到 BUILD_DIR 中

根據 react 的建議
如果你希望檔案在 build 之後維持檔名,就可以把它放進 public 裡面
或者是你需要動態讀檔(也就是我現在需要的),就必須讓檔案名稱維持在某個規則

機密資料怎麼辦

當我好不容易想好一個架構後,我的主管卻點出我把太多資訊放進 public 資料夾了
因為 public 是一個完全赤裸的空間
不只檔名不會變,檔案結構也會保留下來
等於是會把過多資訊公開到網路上
於是他請我再修改一下

但我左思右想,都想不到要怎麼把比較機密的資料藏起來
例如 RPC URL、測試站網址等等
就連各大網站如 uniswap, mStable, beefy 我都能從 dev tool 裡面輕鬆找到 他們每條鏈所用的 rpc url
那這樣我到底應該藏到什麼程度才夠呢?

我發現很多文章跟影片都會說要把 api key 放進.env才不會外洩
但這不是對的
基本上只要網頁會用到的東西
都能透過 dev tool 或某種方式看到
真正能藏 api key 的方法,是利用 proxy 的方式
把呼叫 api 的人(程式)從前端移到後端的 proxy server
然後利用 cors 或其他方式去限制能呼叫的 domain
可以參考本文最後面的參考資料

結論

最後我去告訴主管前端沒辦法把這些資料隱藏起來
我才知道是我會錯意了
他只是希望我把 public 盡量簡化
採用中性的名稱,例如不要特別在檔名上寫 stagine/testnet
並且不要在正式站暴露測試站的資訊
這樣就夠了

不過現在我更加清楚在前端隱藏「會用到的資料」其實是沒有意義的
因為終究要用在瀏覽器上,也就終究有辦法被看到
而且經過這次 code review 我也見識到主管在架構設計上的能力
我花了兩天想出來的結構,除了沒考慮到安全性,用起來也很複雜
但主管花了一個小時左右跟我一起研究出的架構就十分有邏輯
感覺我在這塊還需要訓練一下(他就是這麼跟我說的XD)

參考資料

How to store Ethereum JSON-RPC node API Key in a React app

How can one secure Web3 JSON-RPC API endpoint?

How do I hide an API key in Create React App?