Firebase 和 Algolia 安全搜索没有搜索命中
Firebase and Algolia secured search no search hits
我在使用 Firebase 和 Algolia 实施安全搜索时遇到了一些问题。
我一直在遵循 https://firebase.google.com/docs/firestore/solutions/search -> 添加安全性
的指南
我的问题是似乎一切正常,但我没有收到任何搜索结果。
当用户搜索一个项目时,它会调用一个函数,该函数首先点击一个 firebase 函数来生成一个安全的 API 密钥,其中还包括用于查询的安全过滤器。
Firebase 函数:
app.use(getFirebaseUser);
app.get('/', (req, res) => {
// @ts-ignore
const uid = req.user.uid;
// Create the params object as described in the Algolia documentation:
// https://www.algolia.com/doc/guides/security/api-keys/#generating-api-keys
const params = {
// This filter ensures that only documents where author == uid will be readable
filters: `ownerID:${uid}`,
// We also proxy the uid as a unique token for this key.
userToken: uid,
};
// Call the Algolia API to generate a unique key based on our search key
const key = client.generateSecuredApiKey(ALGOLIA_SEARCH_KEY, params);
// Then return this key as {key: '...key'}
res.json({key});
});
这实际上是来自 firebase 示例的 copy/pasted,除了我将“作者”替换为“ownerID”,这是我想在我的索引中匹配的术语。
getFirebaseUser() 与官方 firebase 示例完全相同 copy/paste。
一旦客户端收到安全的 API 密钥,它就会通过查询传递给 algolia:
const getSearchResults = async (query: string) => {
const index = client.initIndex('things');
try {
const userToken = await auth.currentUser?.getIdToken();
const response = await fetch(GOOGLE_URL, {
headers: { Authorization: `Bearer ${userToken}` },
});
const data = await response.json();
const client = algoliasearch(ALGOLIA_APP_ID, data.key);
const responses = await index.search(query);
console.log(responses);
} catch (err) {
console.error(err.message);
}
};
这也是和例子一样的功能,只不过写的是async/await。 (我确实尝试了一个精确的 copy/paste,结果是一样的)。
此外,该示例还显示了 index.search({query}),其中查询字符串作为对象传入。这也不起作用,Typescript 声明需要一个字符串。
如果我尝试将 initIndex 更改为不存在的索引,我会收到一条错误消息,指出它不存在。这告诉我我的应用程序和 algolia 之间的连接正在按预期工作。
返回的对象如下所示:
exhaustiveNbHits: true
hits: []
hitsPerPage: 20
nbHits: 0
nbPages: 0
page: 0
params: "query=test&filters=ownerID%3AKK3oXEkrIKb31BECDSJPMdgvTBz2&userToken=KK3oXEkrIKb31BECDSJPMdgvTBz2"
processingTimeMS: 1
query: "test"
如果我进行常规搜索:
const getSearchResults = async (query: string) => {
const client = algoliasearch(ALGOLIA_APP_ID, ALGOLIA_SEARCH_API_KEY);
const index = client.initIndex('things');
const responses = await index.search(query);
console.log(responses);
};
我确实得到了点击:
exhaustiveNbHits: true
hits: Array(1)
0: {productName: "test ja", purchaseDate: "15.03.2021", purchasedFrom: "ok", ownerID: "KK3oXEkrIKb31BECDSJPMdgvTBz2", objectID: "25BadjQxUjRjkjH9ZnwW", …}
length: 1
__proto__: Array(0)
hitsPerPage: 20
nbHits: 1
nbPages: 1
page: 0
params: "query=test"
processingTimeMS: 1
query: "test"
这实际上是在绕过整个云功能,这意味着问题一定出在生成安全 API 密钥、参数或其他东西上。
Algolia 中存储的索引数据如下所示:
objectID "25BadjQxUjRjkjH9ZnwW"
productName "test ja"
purchaseDate "15.03.2021"
purchasedFrom "ok"
ownerID "KK3oXEkrIKb31BECDSJPMdgvTBz2"
这意味着我应该在 ownerID 上点击,我在云函数中有它。
编辑:
将参数对象的过滤器设置为空字符串时,我收到了搜索结果。过滤器的实现方式可能有问题。
感谢您对此进行调查。如果能得到所有帮助,我将不胜感激!
斯蒂芬·瓦卢瓦
我正在接触 algolia,并找出问题所在。
代码或搜索的设置方式没有任何问题。
文档中没有提到的一件事是我匹配的属性 (ownerID) 没有声明为分面属性。
通过转到 Algolia 应用程序中的配置 -> Facets,并在那里添加对象键,一切都按预期进行。 (将其设置为 'not searchable')。此属性不应该是可搜索的。它应该只用于将索引与正确的用户匹配。
如果有人使用 Algolia 进行安全搜索,无论您是否使用 Firebase 函数或其他后端,都必须在 Facets 中设置过滤器中的属性。
我在使用 Firebase 和 Algolia 实施安全搜索时遇到了一些问题。 我一直在遵循 https://firebase.google.com/docs/firestore/solutions/search -> 添加安全性
的指南我的问题是似乎一切正常,但我没有收到任何搜索结果。
当用户搜索一个项目时,它会调用一个函数,该函数首先点击一个 firebase 函数来生成一个安全的 API 密钥,其中还包括用于查询的安全过滤器。
Firebase 函数:
app.use(getFirebaseUser);
app.get('/', (req, res) => {
// @ts-ignore
const uid = req.user.uid;
// Create the params object as described in the Algolia documentation:
// https://www.algolia.com/doc/guides/security/api-keys/#generating-api-keys
const params = {
// This filter ensures that only documents where author == uid will be readable
filters: `ownerID:${uid}`,
// We also proxy the uid as a unique token for this key.
userToken: uid,
};
// Call the Algolia API to generate a unique key based on our search key
const key = client.generateSecuredApiKey(ALGOLIA_SEARCH_KEY, params);
// Then return this key as {key: '...key'}
res.json({key});
});
这实际上是来自 firebase 示例的 copy/pasted,除了我将“作者”替换为“ownerID”,这是我想在我的索引中匹配的术语。
getFirebaseUser() 与官方 firebase 示例完全相同 copy/paste。
一旦客户端收到安全的 API 密钥,它就会通过查询传递给 algolia:
const getSearchResults = async (query: string) => {
const index = client.initIndex('things');
try {
const userToken = await auth.currentUser?.getIdToken();
const response = await fetch(GOOGLE_URL, {
headers: { Authorization: `Bearer ${userToken}` },
});
const data = await response.json();
const client = algoliasearch(ALGOLIA_APP_ID, data.key);
const responses = await index.search(query);
console.log(responses);
} catch (err) {
console.error(err.message);
}
};
这也是和例子一样的功能,只不过写的是async/await。 (我确实尝试了一个精确的 copy/paste,结果是一样的)。 此外,该示例还显示了 index.search({query}),其中查询字符串作为对象传入。这也不起作用,Typescript 声明需要一个字符串。
如果我尝试将 initIndex 更改为不存在的索引,我会收到一条错误消息,指出它不存在。这告诉我我的应用程序和 algolia 之间的连接正在按预期工作。
返回的对象如下所示:
exhaustiveNbHits: true
hits: []
hitsPerPage: 20
nbHits: 0
nbPages: 0
page: 0
params: "query=test&filters=ownerID%3AKK3oXEkrIKb31BECDSJPMdgvTBz2&userToken=KK3oXEkrIKb31BECDSJPMdgvTBz2"
processingTimeMS: 1
query: "test"
如果我进行常规搜索:
const getSearchResults = async (query: string) => {
const client = algoliasearch(ALGOLIA_APP_ID, ALGOLIA_SEARCH_API_KEY);
const index = client.initIndex('things');
const responses = await index.search(query);
console.log(responses);
};
我确实得到了点击:
exhaustiveNbHits: true
hits: Array(1)
0: {productName: "test ja", purchaseDate: "15.03.2021", purchasedFrom: "ok", ownerID: "KK3oXEkrIKb31BECDSJPMdgvTBz2", objectID: "25BadjQxUjRjkjH9ZnwW", …}
length: 1
__proto__: Array(0)
hitsPerPage: 20
nbHits: 1
nbPages: 1
page: 0
params: "query=test"
processingTimeMS: 1
query: "test"
这实际上是在绕过整个云功能,这意味着问题一定出在生成安全 API 密钥、参数或其他东西上。
Algolia 中存储的索引数据如下所示:
objectID "25BadjQxUjRjkjH9ZnwW"
productName "test ja"
purchaseDate "15.03.2021"
purchasedFrom "ok"
ownerID "KK3oXEkrIKb31BECDSJPMdgvTBz2"
这意味着我应该在 ownerID 上点击,我在云函数中有它。
编辑: 将参数对象的过滤器设置为空字符串时,我收到了搜索结果。过滤器的实现方式可能有问题。
感谢您对此进行调查。如果能得到所有帮助,我将不胜感激!
斯蒂芬·瓦卢瓦
我正在接触 algolia,并找出问题所在。
代码或搜索的设置方式没有任何问题。 文档中没有提到的一件事是我匹配的属性 (ownerID) 没有声明为分面属性。
通过转到 Algolia 应用程序中的配置 -> Facets,并在那里添加对象键,一切都按预期进行。 (将其设置为 'not searchable')。此属性不应该是可搜索的。它应该只用于将索引与正确的用户匹配。
如果有人使用 Algolia 进行安全搜索,无论您是否使用 Firebase 函数或其他后端,都必须在 Facets 中设置过滤器中的属性。