admin.auth().verifyIdToken(tokenId)
.then((decoded) => res.status(200).send(decoded))
我了解
verifyIdToken()
可以验证来自 Firebase 身份验证客户端的用户 ID token 。但是,我们需要通过确保数据库查询受到为 token 中标识的用户定义的数据库安全规则的限制来保护我们的云功能。鉴于默认情况下 admin SDK 具有无限访问权限,我如何将其访问权限限制为仅经过身份验证的用户的访问权限?
最佳答案
看看下面的 HTTPS 函数。它执行以下任务:
userApp
一起使用对某个保护路径进行数据库查询。 userApp.delete()
在所有情况下都被调用。 不要忘记这样做,否则会随着更多用户访问此功能而导致内存泄漏。 这是一个工作函数:
const admin = require("firebase-admin")
admin.initializeApp()
exports.authorizedFetch = functions.https.onRequest((req, res) => {
let userApp
let response
let isError = false
const token = req.query['token']
admin.auth().verifyIdToken(token)
.then(decoded => {
// Initialize a new instance of App using the Admin SDK, with limited access by the UID
const uid = decoded.uid
const options = Object.assign({}, functions.config().firebase)
options.databaseAuthVariableOverride = { uid }
userApp = admin.initializeApp(options, 'user')
// Query the database with the new userApp configuration
return admin.database(userApp).ref("/some/protected/path").once('value')
})
.then(snapshot => {
// Database fetch was successful, return the user data
response = snapshot.val()
return null
})
.catch(error => {
// Database fetch failed due to security rules, return an error
console.error('error', error)
isError = true
response = error
return null
})
.then(() => {
// This is important to clean up, returns a promise
if (userApp) {
return userApp.delete()
}
else {
return null
}
})
.then(() => {
// send the final response
if (isError) {
res.status(500)
}
res.send(response)
})
.catch(error => {
console.error('final error', error)
})
})
再次注意
userApp.delete()
应在所有情况下调用以避免泄漏 App 实例。如果您的想法是根据用户为每个新应用程序赋予一个唯一的名称,这不是一个好主意,因为当新用户继续访问此功能时,您仍然可能会耗尽内存。每次通话都要清理干净以确保安全。另请注意
userApp.delete()
应该叫 之前 响应已发送,因为发送响应会终止函数,并且您不希望清理因任何原因而中断。
关于javascript - 如何使用经过身份验证的 id token 和数据库规则保护 Firebase Cloud Function HTTP 端点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48575730/