meilisearch-go 租户 Token 教程:如何用 JWT 实现多租户搜索权限隔离
【免费下载链接】meilisearch-goGolang wrapper for the Meilisearch API项目地址: https://gitcode.com/gh_mirrors/me/meilisearch-go
meilisearch-go 是 Meilisearch 官方的 Go 语言客户端,而**租户 Token(Tenant Token)**正是它在多租户场景下提供的搜索权限隔离利器。本教程将带你从零掌握如何用 JWT 生成租户 Token,让不同用户只能搜索到自己有权访问的数据——无需为每个租户单独建索引,一套搜索后端轻松搞定权限控制。
为什么需要多租户搜索权限隔离?🤔
想象一个 SaaS 应用:多租户共享一套数据,比如电商平台里不同商家共用商品索引、文档系统里不同团队共用文档索引。如果所有用户都能搜到全部数据,隐私就彻底失控了。
传统方案要么为每个租户建独立索引(索引爆炸、维护成本高),要么每次搜索都手动拼接过滤条件(容易漏写、权限难收敛)。而Meilisearch 租户 Token把权限规则直接"签"进令牌里,服务端自动执行过滤,从根上解决这两个痛点。
租户 Token 的核心原理:JWT 签名 🔐
Meilisearch 的租户 Token 本质是一个JWT(JSON Web Token),由 SDK 用 API Key 作为密钥、以 HS256 算法签名生成。它包含两个关键字段:
| 字段 | 作用 |
|---|---|
apiKeyUid | 父级 API Key 的 UID,标识令牌的权限来源 |
searchRules | 搜索规则,定义可访问的索引与过滤条件 |
当客户端拿着租户 Token 发起搜索时,Meilisearch 会校验签名 + 叠加 searchRules 过滤,天然实现搜索权限隔离。在 meilisearch-go 中,这一切封装在GenerateTenantToken一个方法里,对应接口定义见 meilisearch_interface.go。
准备工作:搭建环境 ⚙️
动手前先准备好两样东西:
安装依赖(Go 1.21+):
go get github.com/meilisearch/meilisearch-go想阅读源码或跑集成测试?可以 clone 仓库到本地:
git clone https://gitcode.com/gh_mirrors/me/meilisearch-go准备 API Key:通过客户端创建一个带
search权限的 Key,拿到它的UID和Key值(Key 的 UID 是生成租户 Token 的必填参数,格式要求为 UUID v4)。创建 Key 的方法见 meilisearch.go。
初始化客户端的标准写法:
client := meilisearch.New("http://localhost:7700", meilisearch.WithAPIKey("你的APIKey"))快速上手:三步生成租户 Token 🚀
GenerateTenantToken接收三个参数:apiKeyUID(API Key 的 UID)、searchRules(搜索规则)、options(可选配置)。完整实现见 meilisearch.go。
第一步:编写 searchRules
searchRules := map[string]interface{}{ "products": map[string]string{ "filter": "tenant_id = 42", // 只允许搜索当前租户的数据 }, }第二步:生成令牌
apiKeyUID := "父级APIKey的UID" token, err := client.GenerateTenantToken(apiKeyUID, searchRules, nil) if err != nil { log.Fatal(err) } fmt.Println(token) // 一段 JWT 字符串第三步:把令牌交给前端/客户端,由它代替 API Key 发起搜索。前端拿到的永远只是受限的租户 Token,主 Key 绝不泄露。
searchRules 的两种玩法:全局规则与索引级过滤 🎯
searchRules 非常灵活,对应两种典型用法:
玩法一:所有索引统一规则(用*通配)
searchRules := map[string]interface{}{ "*": map[string]string{ "filter": "tenant_id = 42", }, }玩法二:按索引精细化控制(不同索引不同策略)
searchRules := map[string]interface{}{ "products": map[string]string{ "filter": "tenant_id = 42", }, "reviews": map[string]string{ "filter": "owner_id = 7", }, }对应测试用例可在 meilisearch_test.go 中查看,覆盖了多索引过滤、单索引过滤等多种场景。
进阶配置:过期时间与指定签名密钥 ⏰
GenerateTenantToken的第三个参数是*TenantTokenOptions,结构定义见 types.go,支持两个字段:
APIKey:自定义签名密钥。不填则默认使用初始化客户端时的 API Key;ExpiresAt:令牌过期时间(注意使用 UTC 时间),到期后令牌自动失效。
options := &meilisearch.TenantTokenOptions{ APIKey: "用于签名的APIKey", ExpiresAt: time.Now().Add(24 * time.Hour).UTC(), } token, err := client.GenerateTenantToken(apiKeyUID, searchRules, options)给租户 Token 设置过期时间,能让权限隔离更进一步——即使令牌泄露,也会自动失效。
常见报错与避坑指南 🛡️
GenerateTenantToken内置了严格校验,以下是高频报错原因对照表(校验逻辑见 meilisearch.go):
| 报错场景 | 原因与解决 |
|---|---|
| searchRules 为 nil | 搜索规则不能为空,至少给一个空对象{} |
| 提示缺少 API Key | 既没在 options 里传APIKey,客户端初始化时也没配 Key |
| apiKeyUid 格式错误 | 必须是合法的 UUID v4 格式,校验函数见 helper.go |
| expiresAt 过期 | 过期时间必须晚于当前时间 |
实战收尾:用租户 Token 发起搜索 ✅
生成令牌后,用WithAPIKey传入令牌即可搜索,示例见 examples/search/main.go:
searchClient := meilisearch.New( "http://localhost:7700", meilisearch.WithAPIKey(token), // 传入租户 Token ) result, err := searchClient.Index("products").Search("手机", &meilisearch.SearchRequest{})Meilisearch 会自动在products索引上叠加tenant_id = 42过滤,返回结果天然只属于该租户,权限隔离即刻生效。
小结 💡
通过 meilisearch-go 的GenerateTenantToken,只需几行代码就能基于 JWT 实现强大的多租户搜索权限隔离:一套索引、一套后端,却能按租户精准投放搜索结果。配合过期时间与索引级过滤规则,足以应对绝大多数 SaaS 权限场景。现在就动手试试,让你的搜索服务安全又优雅!
【免费下载链接】meilisearch-goGolang wrapper for the Meilisearch API项目地址: https://gitcode.com/gh_mirrors/me/meilisearch-go
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考