如何在多租戶應用程式中使用 Meilisearch
在本教學中,您將學習如何受益於 Meilisearch 提供的租戶權杖功能。我們將使用 Meilisearch Javascript SDK 建立一個應用程式,該應用程式將使用租戶權杖來根據不同的使用者名稱限制對資料的存取。

**什麼是多租戶?**
在軟體開發中,多租戶意味著多個使用者(也稱為租戶)共享相同的運算資源,但對系統範圍的資料有不同的存取權。在 Meilisearch 中,您可能會擁有一個包含屬於多個不同租戶資料的索引。在這種情況下,您的租戶必須只能搜尋他們自己的文件。
您可以使用租戶權杖來達成此目的。
租戶權杖
租戶權杖是加密資料的小型封包,證明使用者可以存取特定的索引。它們包含安全憑證和關於使用者允許查看該索引中哪些文件的指示。
租戶權杖的主要用例是根據使用者權限強制執行限制。
使用者可以使用 Meilisearch SDK 或 自訂程式碼來產生租戶權杖。
租戶權杖不需要您設定任何特定的執行個體選項或索引設定。它們也應該是短期的—Meilisearch 不會儲存或追蹤產生的權杖。
當使用 SDK 產生租戶權杖時,您需要四個參數
- 搜尋規則:搜尋規則是一組定義搜尋參數的指令,這些參數將在每次使用特定租戶權杖發出的查詢中強制執行。
- API 金鑰:權杖具有與用於產生它的 API 金鑰相同的索引存取權。
- API 金鑰 uid:用於產生權杖的 API 金鑰的 uid 允許檢查所使用的 API 金鑰是否有效。
- 到期日(選用):租戶權杖的到期日
您可以在文件中閱讀更多關於租戶權杖有效負載的資訊。
**需求**
**建立租戶權杖**
可以使用 Meilisearch Javascript SDK 中提供的 generateTenantToken
函式建立租戶權杖。
以下是使用 Meilisearch SDK 建立租戶權杖的簡單範例
client = new Meilisearch({ host: "<https://127.0.0.1:7700>", apiKey: "masterKey", }); // We have created a Meilisearch instance in JavaScript and we will use this to create the tenant token. const apiKey = "rkDxFUHd02193e120218f72cc51a9db62729fdb4003e271f960d1631b54f3426fa8b2595"; const apiKeyUid = "85c3c2f9-bdd6-41f1-abd8-11fcf80e0f76"; const expiresAt = new Date("2025-01-01"); // Now we have declared the API Key, its uid, as well as the expiration date for the token. searchRules = { "*": { filter: "user_id = 1", }, }; // Here we have defined the search rules that will apply restrictions on the search results. tenantToken = client.generateTenantToken(apiKeyUid, searchRules, { expiresAt: expiresAt, apiKey: apiKey, }); // Now the generateTenantToken function will create a tenant token and Meilisearch can validate this token with the apiKey.
當 Meilisearch 收到帶有租戶權杖的搜尋查詢時,它會解碼該權杖並將搜尋規則應用於搜尋請求。
應用程式使用
假設我們在 Meilisearch 執行個體中建立了一個醫療記錄系統,其中包含 patient_medical_record
索引。此索引包含一份病患清單以及他們的詳細資料。我們可以使用租戶權杖來限制對此資料的存取。
範例資料集
[ { "patient": "John", "description": "John is in room number 2 and is suffering from Covid", "roomNumber": 1, "isDoctorAppointed": true }, { "patient": "Zia", "description": "Zia is in room number 3 and is suffering from Dengue", "roomNumber": 2, "isDoctorAppointed": true }, { "patient": "Kevin", "description": "Kevin is in room number 4 and is suffering from Typhoid", "roomNumber": 3, "isDoctorAppointed": false } ]
在上述資料集中,我們有三位病患:John、Zia 和 Kevin。目的是限制 Zia 存取 Kevin 和 John 的資料。為了達到這個目的,我們需要為她建立一個包含一組搜尋規則的租戶權杖。
對於這種情況,搜尋規則可以指定為
"searchRules": { "patient_medical_record": { "filter": "patient = Zia" } }
Zia 的租戶權杖將在搜尋請求時應用,這會傳回
[ { "patient": "Zia", "description": "Zia is in room number 3 and is suffering from Dengue", "roomNumber": 2, "isDoctorAppointed": true } ]
這是一個簡單的使用案例,但我們可以修改規則以滿足更複雜的需求。
**將多租戶功能整合到您的應用程式中**
我們將使用以上範例來建立一個應用程式,以顯示 Meilisearch 索引中的病患。然後,我們將使用多租戶來限制對此資料的存取。
-
下載應用程式
從 Github 上的 Meilisearch 教學儲存庫複製示範應用程式的樣板程式碼。
使用以下命令
git clone https://github.com/meilisearch/tutorials
樣板程式碼存在於 src/tenant-token-tutorial
目錄中。
cd src/tenant-token-tutorial
此程式碼包含一個在 React.js
中建立的前端應用程式和一個在 Express.js/Node.js
中的後端伺服器。
-
啟動 Meilisearch
有多種方法可以下載並執行 Meilisearch 執行個體。執行 Meilisearch 執行個體最簡單的方法是使用Meilisearch Cloud,提供 14 天免費試用,無需信用卡。Meilisearch 是開源的,在此示範中,我們將使用 Docker 在本地執行它
docker pull getmeili/meilisearch:v1.0 docker run -it --rm -p 7700:7700 -e MEILI_MASTER_KEY='masterKey' -v $(pwd)/meili_data:/meili_data getmeili/meilisearch:v1.0 meilisearch --env="development"
啟動 Meilisearch 時,別忘了如上所示定義一個主金鑰。它將建立產生租戶權杖所需的 API 金鑰。
Meilisearch 執行個體將在 IP 位址上執行:https://127.0.0.1:7700
。
-
將資料新增到 Meilisearch
基本目錄的
seed
資料夾中有一個data.json
檔案,其中包含一份有 10 種疾病的 10 位病患清單,每位病患有 100 筆記錄,每筆記錄都有一個病房號碼和一些病患詳細資料。我們將把資訊輸入到 Meilisearch 中。將終端目錄變更為
seed
資料夾,並使用以下命令將給定的資料新增至 Meilisearch 執行個體
npm install # This command will install node dependencies npm start # This command will add all the data from data.json to Meilisearch
-
啟動前端伺服器
導覽至
frontend
資料夾,並安裝所有應用程式相依性以及 Meilisearch Javascript SDK
npm install # To install all the react application dependency npm install meilisearch # To install the Meilisearch SDK
安裝專案的所有相依性可能需要一些時間。
讓我們使用以下命令啟動並執行前端 React 伺服器
npm start
應用程式將在 IP 位址上執行:https://127.0.0.1:3000
。
-
新增建立租戶權杖的功能
導覽至
backend
資料夾,並使用以下命令安裝所有相依性
npm install
在 backend
資料夾中,開啟 index.js
檔案。它包含 API 的路由和邏輯。
已經定義了一個端點用於產生租戶權杖
app.get("/create-tenant-token", async (req, res) => { const { value: patientName } = req.query; /* Add functionality to create Tenant token */ });
現在,我們將在函式中的註解下方新增功能。
我們需要 API 金鑰、搜尋規則和到期日才能產生租戶權杖。
可以從 Javascript SDK 的 getKeys
方法取得 API 金鑰。getKeys
方法會傳回一份 API 金鑰清單,我們可以從中選擇一個來用於租戶權杖產生流程。為此,請將以下程式碼新增至上述 API 方法
const { results } = await client.getKeys(); const apiKey = results.filter( (res) => res.name === "Default Search API Key" )[0].key; const apiKeyUid = results.filter( (res) => res.name === "Default Search API Key" )[0].uid;
我們也可以使用 createKey
函式來產生新的 API 金鑰。
您可以在Meilisearch 文件中閱讀更多關於 API 金鑰的資訊。
透過指定搜尋規則,我們現在可以產生有效負載。使用以下程式碼來定義有效負載
const payload = { patient_medical_record: { filter: `patient = ${patientName}`, }, };
如果我們需要權杖在一年後到期,我們可以在建立權杖時設定到期日,如下所示。
const expiresAt = new Date( new Date().setFullYear(new Date().getFullYear() + 1) );
要產生權杖,我們現在可以使用 Meilisearch Javascript SDK 中的 generateTenantToken
函式,並使用 res.json()
函式回傳產生的權杖。
const tenantToken = client.generateTenantToken(apiKeyUid, payload, { apiKey, expiresAt, }); return res.json({ token: tenantToken });
這是端點應該如何實作的
app.get("/create-tenant-token", async (req, res) => { const { value: patientName } = req.query; /* Add functionality to create Tenant token */ const { results } = await client.getKeys(); const apiKey = results.filter( (res) => res.name === "Default Search API Key" )[0].key; const apiKeyUid = results.filter( (res) => res.name === "Default Search API Key" )[0].uid; const payload = { patient_medical_record: { filter: `patient = ${patientName}`, }, }; const expiresAt = new Date( new Date().setFullYear(new Date().getFullYear() + 1) ); const tenantToken = client.generateTenantToken(apiKeyUid, payload, { apiKey, expiresAt, }); return res.json({ token: tenantToken }); });
前端請求的端點會像這樣
https://127.0.0.1:5001/create-tenant-token?value=John
使用 API 中的值 John
建立包含搜尋規則的酬載。
讓我們使用 npm start
命令來啟動 express API 伺服器。伺服器將會在 https://127.0.0.1:5001
上執行。
-
將您的 API 與前端程式碼連接
在文字方塊中輸入病患姓名。提交輸入表單後,會向後端發送 API 呼叫,後端應該會回傳租戶權杖。當我們需要特定病患的資料時,可以將此權杖傳遞給 Meilisearch 實例。
現在必須設定前端程式碼,從伺服器請求租戶權杖。我們將使用 axios 函式庫 來從我們開發的
/create-tenant-token
API 取得權杖,並將病患姓名傳遞至 API 的參數中。開啟
/src/utils
資料夾中的index.js
檔案,並尋找getTenantToken
函式。此函式會向伺服器發出請求並接收回租戶權杖。將以下程式碼新增至 getTenantToken 方法
export const getTenantToken = async (patientName) => { const response = await axios({ url: `${apiHost}/create-tenant-token`, method: "GET", params: { value: patientName, }, }); return response.data.token; };
-
測試實作的功能
讓我們測試實作;首先按一下
Create a Tenant token
按鈕。在指定的文字方塊中輸入姓名
Kevin
,然後按一下Create a Tenant token
按鈕。這會產生租戶權杖。Meilisearch 將根據病患提供的租戶權杖取得資料,在此過程中充當驗證器。
結論
我們已根據病患姓名限制對醫療記錄的存取。透過使用 Meilisearch 的多租戶功能,我們能夠輕鬆完成這一切。這是一個浮現在腦海中的相當基本的使用案例情境。該功能可以像您希望的那樣複雜。例如,我們可以在電子銀行應用程式中實作多租戶,其中中央權限是銀行,而客戶是具有存取權限的不同銀行帳戶的租戶。
如果您有任何問題,請在 Discord 上加入我們。如需有關 Meilisearch 的更多資訊,請查看我們的 Github 儲存庫和我們的官方文件。