境變量完全指南:Web 端與 API 端的加載、注入與安全實踐)
后端前端Web框架開發(fā)工具【免費下載鏈接】redwoodRedwoodGraphQL項目地址https://gitcode.com/gh_mirrors/re/redwood點擊查看免費下載Redwood 應(yīng)用由 APINode.js 目標(biāo)與 Web瀏覽器目標(biāo)兩個固定 Side 組成二者獲取環(huán)境變量的方式截然不同。本文基于 Redwood 6.x 官方文檔 environment-variables.md 展開系統(tǒng)講解.env與.env.defaults的加載機(jī)制、Web 端兩種構(gòu)建期變量注入方案redwood.toml的includeEnvironmentVariables與REDWOOD_ENV_前綴、API URL 的全局注入、開發(fā)期FatalErrorPage編輯器配置以及敏感信息保護(hù)并結(jié)合倉庫源碼印證其底層實現(xiàn)讓你能按環(huán)境正確配置、安全使用環(huán)境變量??傆[Redwood 的兩種 Side、兩種加載路徑Redwood 應(yīng)用有兩個固定的 Side各自有唯一的目標(biāo)運(yùn)行環(huán)境API Side目標(biāo)為 Node.js可以直接通過process.env.VAR_NAME在服務(wù)端代碼Functions、Services、GraphQL 解析器等中讀取環(huán)境變量Web Side目標(biāo)為瀏覽器沒有process.env這個概念必須依賴構(gòu)建期替換build-time replacement把變量值烘焙進(jìn)靜態(tài)產(chǎn)物。所有環(huán)境變量文件的加載都基于 dotenv 生態(tài)。具體來說Redwood 使用的是 dotenv-defaults因此同時支持加載.env和.env.defaults兩個文件.env存放真實值通常不入庫.env.defaults存放可提交到版本庫的默認(rèn)值/示例值。dotenv 的完整語法規(guī)則如多行值、引號與轉(zhuǎn)義可參考其官方 Rules 章節(jié)。在 Web SideRedwood 還額外配置了 Vite將所有對process.env變量的引用在構(gòu)建期替換為變量的實際值——這正是瀏覽器端能看到環(huán)境變量的根本機(jī)制。環(huán)境變量文件從何而來CLI 入口與加載順序為了讓.env與.env.defaults中的變量進(jìn)入process.env必須在某個入口調(diào)用 dotenv 的config函數(shù)。在 Redwood 中這個入口就是CLI每次運(yùn)行yarn rw命令時都會加載。文檔中給出的經(jīng)典實現(xiàn)位于packages/cli/src/index.jsimport { config } from dotenv-defaults config({ path: path.join(getPaths().base, .env), encoding: utf8, defaults: path.join(getPaths().base, .env.defaults), })在當(dāng)前的倉庫中這一職責(zé)已演進(jìn)為packages/cli-helpers/src/lib/loadEnvFiles.ts中的loadEnvFiles()與loadDefaultEnvFiles()加載邏輯更完整export function loadDefaultEnvFiles(cwd: string) { dotenvDefaultsConfig({ path: path.join(cwd, .env), defaults: path.join(cwd, .env.defaults), multiline: true, }) }實際加載順序為loadDefaultEnvFiles(base)加載.env與.env.defaultsdotenv-defaults 保證.env中的值優(yōu)先于.env.defaultsloadNodeEnvDerivedEnvFile(base)若存在NODE_ENV則繼續(xù)加載.env.${NODE_ENV}如.env.production并覆蓋已有值loadUserSpecifiedEnvFiles(base, loadEnvFiles)若命令行帶有--load-env-files suffix參數(shù)則加載對應(yīng)的.env.suffix并覆蓋。整個加載過程由process.env.REDWOOD_ENV_FILES_LOADED標(biāo)記保證只執(zhí)行一次參見 loadEnvFiles.ts。注意如果yarn rw dev已經(jīng)在運(yùn)行修改.env文件后本地應(yīng)用不會立即生效必須停止并重新運(yùn)行yarn rw dev。Web Side讓瀏覽器訪問環(huán)境變量的兩種方案Heads Up要讓 Web Side 在生產(chǎn)環(huán)境訪問環(huán)境變量必須配置下面兩種方案之一。Redwood 官方推薦Option 1redwood.toml的includeEnvironmentVariables因為它最健壯。Option 1redwood.toml中的includeEnvironmentVariables在redwood.toml的[web]段落中把需要暴露給 Web 端的變量名加入數(shù)組[web] includeEnvironmentVariables [SECRET_API_KEY, ANOTHER_ONE]加入該數(shù)組后這些變量在生產(chǎn)構(gòu)建中會通過process.env.SECRET_API_KEY被替換為實際值。源碼層面該替換由 Vite 插件完成packages/vite/src/lib/envVarDefinitions.ts會為每個列出的變量同時生成import.meta.env.${envName}與process.env.${envName}兩條定義見 envVarDefinitions.ts從而保證代碼中兩種寫法都能在構(gòu)建期完成替換。Option 2REDWOOD_ENV_前綴在.env中只要變量名以REDWOOD_ENV_開頭就會被自動注入 Web 端REDWOOD_ENV_MY_VAR_NAMEsome value代碼中通過process.env.REDWOOD_ENV_MY_VAR_NAME訪問構(gòu)建期同樣會被動態(tài)替換為實際值。envVarDefinitions.ts中遍歷process.env所有鍵凡以REDWOOD_ENV_開頭的都會生成import.meta.env與process.env兩條替換定義見 envVarDefinitions.ts。安全警示瀏覽器端的明文暴露無論采用哪種方案凡是注入 Web 端的變量最終都會以明文形式存在于靜態(tài) JS/HTML 產(chǎn)物中。任何人查看你站點的源碼都可能看到REDWOOD_ENV_SECRET_API_KEY的真實值。這是向瀏覽器交付靜態(tài) JS 與 HTML 這一模型固有的限制。因此只向 Web 端暴露非敏感的公開配置如 API 域名、公鑰、站點標(biāo)題等真正的密鑰數(shù)據(jù)庫密碼、簽名私鑰、第三方 Secret只應(yīng)保留在 API Side各認(rèn)證提供商在setup命令的提示中也反復(fù)強(qiáng)調(diào)這一原則——例如 Clerk 的 setupHandler.ts 會提醒你把CLERK_PUBLISHABLE_KEY加入includeEnvironmentVariables而 Firebase 的 setupHandler.ts 則提示加入FIREBASE_API_KEY與FIREBASE_AUTH_DOMAIN——這些都是公開也安全的發(fā)布型密鑰。與redwood.toml其他配置的配合includeEnvironmentVariables在redwood.toml中的完整定義與apiUrl、apiGraphQLUrl等鍵同屬[web]段默認(rèn)值為[]。若部署在不同環(huán)境需要不同的apiUrlredwood.toml本身也支持${envVar:[fallback]}插值語法詳見 app-configuration-redwood-toml.md[web] title App running on ${APP_TITLE} port ${PORT:8910} apiUrl ${API_URL:/.redwood/functions} includeEnvironmentVariables []兩點提醒fallback 值始終是字符串這些值在構(gòu)建期完成插值。這與 Web 端環(huán)境變量構(gòu)建期替換的特性一致。Web SideAPI URL 的全局注入Redwood 會自動把redwood.toml中[web]段落的 API URL 配置暴露到全局對象window或global上無需任何額外配置redwood.tomlkeyAvailable globally asDescriptionapiUrlglobal.RWJS_API_URLURL 或絕對路徑指向 api-serverapiGraphQLUrlglobal.RWJS_API_GRAPHQL_URLURL 或絕對路徑指向 GraphQL Function例如global.RWJS_API_GRAPHQL_URL給出 GraphQL endpoint 的完整地址。在redwood.toml中apiGraphQLUrl的默認(rèn)值是${apiUrl}/graphql參見 app-configuration-redwood-toml.md。從源碼看packages/vite/src/lib/envVarDefinitions.ts的RWJS_ENV段正是從配置中派生這兩個全局變量RWJS_ENV: { RWJS_API_GRAPHQL_URL: rwConfig.web.apiGraphQLUrl ?? rwConfig.web.apiUrl /graphql, RWJS_API_URL: rwConfig.web.apiUrl, // ... }默認(rèn)配置下apiUrl /.redwood/functions因此 GraphQL endpoint 默認(rèn)為/.redwood/functions/graphql。開發(fā)期增強(qiáng)FatalErrorPage 與編輯器跳轉(zhuǎn)Redwood 內(nèi)置了FatalErrorPage當(dāng)前版本實現(xiàn)于packages/web/src/components/DevFatalErrorPage.tsx當(dāng)開發(fā)環(huán)境出錯時會展示堆棧信息與請求詳情幫助快速定位問題。注意FatalErrorPage不會被打包進(jìn)生產(chǎn)構(gòu)建僅用于開發(fā)調(diào)試。堆棧跟蹤中的源碼文件鏈接會嘗試用你的編輯器打開默認(rèn)使用 VSCode。你可以通過設(shè)置環(huán)境變量覆蓋編輯器REDWOOD_ENV_EDITORvscode在源碼中DevFatalErrorPage.tsx通過RWJS_DEBUG_ENV.REDWOOD_ENV_EDITOR || vscode讀取該值見 DevFatalErrorPage.tsx而envVarDefinitions.ts則將其放入RWJS_DEBUG_ENV供開發(fā)期使用見 envVarDefinitions.ts??梢栽O(shè)置為vscode、webstorm、sublime、atom等編輯器對應(yīng)的 scheme。API Side開發(fā)與生產(chǎn)開發(fā)環(huán)境API Side 在開發(fā)中可直接讀取.env與.env.defaults中定義的變量用法就是標(biāo)準(zhǔn)的process.env.VAR_NAME。例如在.env中定義HELLO_ENVhello world然后生成一個 hello Functionyarn rw generate function hello并在響應(yīng)體里引用該變量export const handler async (event, context) { return { statusCode: 200, body: ${process.env.HELLO_ENV}, } }啟動開發(fā)服務(wù)后訪問 http://localhost:8911/hello可以看到 Function 成功讀取了環(huán)境變量并返回hello world。生產(chǎn)環(huán)境生產(chǎn)環(huán)境中環(huán)境變量由你部署的平臺注入到 serverless 運(yùn)行時。不同平臺有各自的配置入口例如 Netlify 是在Settings Build Deploy Environment中設(shè)置。需要閱讀對應(yīng)托管商的文檔完成配置。需要特別留意部分托管商區(qū)分構(gòu)建環(huán)境與運(yùn)行時環(huán)境。對此 Redwood 給出了明確的配置建議Web Side的變量屬于構(gòu)建期注入應(yīng)配置為build-time variablesAPI Side的變量屬于運(yùn)行時讀取應(yīng)配置為runtime variables。配置錯位會導(dǎo)致生產(chǎn)環(huán)境讀不到變量這是實際部署中最常見的坑之一。保護(hù)敏感信息.env不入庫.env通常包含敏感信息永遠(yuǎn)不要提交到版本庫。實際上 Redwood 項目的默認(rèn).gitignore已經(jīng)顯式忽略了.env你幾乎需要刻意為之才會誤提交.DS_Store .env .netlify dev.db dist dist-babel node_modules yarn-error.log與之相對.env.defaults是用于存放默認(rèn)值/示例值的文件可以安全提交便于團(tuán)隊協(xié)作時讓每個人都有一套可運(yùn)行的基線配置。小結(jié)一套按 Side 與環(huán)境落地的配置心法場景方式時機(jī)API 開發(fā)環(huán)境.env/.env.defaults直接寫入process.env.VAR_NAME讀取運(yùn)行時每次yarn rw加載API 生產(chǎn)環(huán)境托管平臺控制臺配置如 Netlify Build Deploy Environment運(yùn)行時配置為 runtime variablesWeb 生產(chǎn)環(huán)境方案一redwood.toml的[web].includeEnvironmentVariables數(shù)組構(gòu)建期替換Web 生產(chǎn)環(huán)境方案二變量名加REDWOOD_ENV_前綴構(gòu)建期替換API URL 注入自動global.RWJS_API_URL/global.RWJS_API_GRAPHQL_URL構(gòu)建期派生開發(fā)期編輯器跳轉(zhuǎn).env中設(shè)置REDWOOD_ENV_EDITOR僅開發(fā)環(huán)境生效核心結(jié)論密鑰只進(jìn) API公開配置才進(jìn) WebWeb 端變量按構(gòu)建期替換來設(shè)計API 端變量按運(yùn)行時讀取來設(shè)計.env永不入庫/api密鑰永不暴露給瀏覽器。理解了加載入口packages/cli-helpers/src/lib/loadEnvFiles.ts與替換機(jī)制packages/vite/src/lib/envVarDefinitions.ts之后你就掌握了 Redwood 環(huán)境變量從文件到運(yùn)行時的完整鏈路。贊分享后端前端Web框架開發(fā)工具【免費下載鏈接】redwoodRedwoodGraphQL項目地址https://gitcode.com/gh_mirrors/re/redwood點擊查看免費下載相關(guān)推薦Redwood 環(huán)境變量完全指南Web 端與 API 端的環(huán)境變量加載、注入與安全實踐Redwood 環(huán)境變量完全指南Web 端與 API 端的環(huán)境變量加載、注入與安全實踐 Redwood 應(yīng)用由 APINode.js與 Web瀏覽器兩后端前端Web框架開發(fā)工具Redwood 環(huán)境變量完全指南Web 端與 API 端的配置、注入與安全實踐Redwood 環(huán)境變量完全指南Web 端與 API 端的配置、注入與安全實踐 本文基于 Redwood 框架 v4.x 官方文檔《Environment V后端前端Web框架開發(fā)工具Redwood 環(huán)境變量完全指南Web 與 API 雙端的配置、注入與安全實踐Redwood 環(huán)境變量完全指南Web 與 API 雙端的配置、注入與安全實踐 RedwoodRedwoodGraphQL將應(yīng)用劃分為 APINode.后端前端Web框架開發(fā)工具創(chuàng)作聲明:本文部分內(nèi)容由AI輔助生成(AIGC),僅供參考