把檢視公開出去
目標:讓外部網頁顯示某張自訂表格的即時資料,不需要登入,也不需要你自己架後端。流程是:先做出檢視、對它鑄造權杖、確認匿名讀者實際看到什麼,最後撤銷。撤銷是這個任務的一部分,不是事後才想的事。
以下都假設你是這張表的版主。每個步驟背後的完整合約見 公開讀取。
1. 先做出要公開的檢視
公開的對象永遠是檢視,不是資料表。檢視是你決定「哪些列、哪些欄」的地方,而且對它的修改會立刻反映到公開 URL:拿掉檢視的篩選或多投影一個欄位,都會擴大公開範圍(除非權杖的 visible_columns/read_filter 另有限制),刪除檢視則會連帶刪除它的權杖。檢視的建立者不需要版主權限就能修改或刪除它,所以請公開你能掌控的檢視。
curl -X POST \
"$BASE_URL/private/module/custom_tables/chatroom/11111111-1111-4111-8111-111111111111/tables/22222222-2222-4222-8222-222222222222/views" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "已上架品項",
"config": {
"columns": ["品項", "單價", "分類"],
"sort": [{ "column": "col_1b2c3d4e_5f60_4a7b_8c9d_0e1f2a3b4c5d", "order": "asc" }]
}
}'設計時有三個限制要遵守。檢視篩選或排序用到的每個欄位最後都必須公開——同時在檢視的 columns 與權杖的 visible_columns 中——否則每次公開讀取都會回統一的 404;所以這個檢視依 品項 排序(sort 的鍵是品項的內部 col_<hex> 鍵:私有的檢視資料列路由會原樣傳遞排序鍵、不做名稱對應,在那裡寫顯示名稱會回 400),也不在 已上架 上篩選(改由下面權杖的 read_filter 處理)。檢視不能帶 computed_filters,sort 與 sort_by 也不能指到 link、rollup、lookup、formula 欄位:這種檢視無法公開,而且如果你事後才加上去,已公開的 URL 會直接停止服務。另外,受 SCP channel 規則治理的資料表完全不能公開,所以如果這張表受 channel 治理,就到此為止,改公開一份不受治理的副本。
2. 鑄造權杖
curl -X POST \
"$BASE_URL/private/module/custom_tables/chatroom/tables/22222222-2222-4222-8222-222222222222/public-read-tokens" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "官網價目表",
"view_id": "33333333-3333-4333-8333-333333333333",
"secretless": true,
"visible_columns": ["品項", "單價"],
"read_filter": { "and": [{ "column": "col_9c1e2f3a_4b5c_4d6e_8f70_819203a4b5c6", "op": "eq", "value": true }] },
"allow_query": false,
"rpm": 120,
"valid_until": null
}'注意鑄造路徑沒有 scope id 那一段。有四件事要刻意決定:
secretless。true表示 URL 就是憑證,這是公開網頁需要的形式。false會產生只顯示一次的 Bearer 密鑰,適合伺服器對伺服器的使用者。visible_columns。 這是一份允許清單,會與檢視的欄位取交集。檢視投影了分類、但這裡不列它,就能讓它不出現在回應中;但不能用它過濾或排序:檢視的篩選或排序若指到未公開欄位,每次讀取都會回統一的 404。read_filter。 要依不想顯示的欄位過濾——這裡是已上架——請把條件放在權杖上,寫成使用該欄位內部col_<hex>鍵值的 row policy。它會收窄資料列,而且不受公開投影的檢查。allow_query。 除非使用端真的需要在檢視之外再過濾、排序或分頁,否則保持false。這是「公開一個頁面」與「公開一個小型查詢 API」的差別。
如果你鑄造的是帶密鑰的權杖,現在就把密鑰存起來,之後不會再顯示。
3. 以匿名讀者的身分驗證
在完全不帶 Authorization 標頭的環境下執行,並且要看回傳內容,不要只看狀態碼:
curl "$BASE_URL/public/module/custom_tables/read/44444444-4444-4444-8444-444444444444/records?limit=5"檢查五件事:
columns只列出你打算公開的欄位。- 每一列都沒有
created_by、pending_approval,也沒有除id以外的任何 id。如果看到別的東西,先停下來,回去讀 公開讀取 再上線。 - 有公開的
formula欄位要有真正的值,而不是null。輸入被隱藏或跨表的公式在這條通道上會解析成null。 - 有公開的
user、social_client或principal欄位顯示的是原始儲存 id(principal值會保留user:/smc:/room:標記),這通常不是你想放在公開頁面上的東西。除非那個 id 本來就該公開,否則把它從visible_columns移除。 - 有公開的
decimal欄位會以精確的十進位字串("12800.00")送達,而不是 JSON 數字——請在頁面上自行格式化。
如果拿到 404,除錯要從私有側做:列出這張表的權杖,確認它沒有被撤銷或過期,然後重新打開檢視,確認它仍然沒有跨表計算語法,而且篩選與排序用到的每個欄位都同時在檢視的 columns 與權杖的 visible_columns 中。如果清單裡根本找不到這個權杖,代表它的檢視已被刪除——權杖會隨之連帶刪除。
4. 交出 URL 時,把它當成憑證
無密鑰權杖的 uuid 就是全部的憑證。把它放在頁面的伺服器端設定或建置產物裡,不要放進公開的 repository,也不要貼在工單裡。它沒辦法收回,只能撤銷。
5. 輪替與撤銷
輪替的順序是:鑄造、部署、驗證、撤銷。
curl -X DELETE \
"$BASE_URL/private/module/custom_tables/chatroom/tables/22222222-2222-4222-8222-222222222222/public-read-tokens/44444444-4444-4444-8444-444444444444" \
-H "Authorization: Bearer $TOKEN"撤銷是永久的:資料列會留著並標記 revoked: true,URL 永遠失效,所以誤撤就只能鑄造新的 URL 並重新部署使用端。撤銷前先看權杖列表裡的 last_used_at,確認是不是還有人在讀。
讓它進版控
形狀確定之後,用 JSONL 文件宣告這個權杖,下一個環境就會得到同樣的公開設定,不必再手動鑄造:
{"kind":"view","table":"prices","ref":"published_items","spec":{"name":"已上架品項","config":{"columns":["item","unit_price","category"],"sort_by":"item","sort_order":"asc"}}}
{"kind":"public_read","table":"prices","ref":"website_price_list","spec":{"view":"published_items","secretless":true,"visible_columns":["item","unit_price"],"read_filter":{"and":[{"column":"published","op":"eq","value":true}]},"rpm":120,"allow_query":false}}文件中的欄位引用是 column 行的 ref(item、unit_price、published——也就是資料表 column 行的 ref),不是顯示名稱。IaC 公開只支援無密鑰,view 必須是受管理的檢視(上面那行 view 就滿足這個條件),而重複 apply 會就地更新權杖,所以 URL 保持不變。要撤銷,請把這一行換成 {"kind":"public_read","table":"prices","ref":"website_price_list","state":"absent"}——absent 行不帶 spec。詳見 public_read 行類型。