我有一个自定义令牌,其中包含有效负载 appid 来识别第三方应用。
我想验证对我的数据的读/写,以便:
/apps
集合中注册我最终偶然发现的答案是相当好,但可能会得到改善。
我要做的第一件事是正确识别自定义令牌中提供的有效负载-因为我正在使用云服务函数来生成有效负载(graphcool),所以我的有效负载是default: { appid }
而不是仅appid
。从那里开始,对权限进行一些重新措词就足以使用我想象中的当前规则成功验证:
service cloud.firestore {
match /databases/{database}/documents {
match /sampleData/{type}/{appName}/{record} {
allow read: if isSignedIn() && isValidApp(database) && ownsExisting() && appIdInExisting()
allow write: if isSignedIn() && isValidApp(database) && ownsPayload() && appIdInPayload()
}
// functions
function isSignedIn () {
return request.auth != null
}
function isValidApp (database) {
return exists(/databases/$(database)/documents/apps/$(request.auth.token.appid))
}
function ownsExisting () {
return resource.data.uid == request.auth.uid
}
function ownsPayload () {
return request.resource.data.uid == request.auth.uid
}
function appIdInExisting () {
return resource.data.app_id == request.auth.token.appid
}
function appIdInPayload () {
return request.resource.data.app_id == request.auth.token.appid
}
}
}
虽然有人可以做得更好。
有什么方法可以验证 appid 而不使用现有请求(也不需要编写 if-else if 链)-就像使用数组一样也许直接在规则中?
我如何确保有效载荷中指定的 appid 与我向客户端第三方应用程序发布服务凭证时所设想的相符?
我认为自己至少可以得到前两个:
service cloud.firestore {
match /databases/{database}/documents {
match /sampleData {
allow read: if isSignedIn() && isValidApp() && ownsExisting() && appIdInExisting()
allow write: if isSignedIn() && isValidApp() && ownsPayload() && appIdInPayload()
}
// functions
function isSignedIn () {
return request.auth != null
}
function isValidApp () {
return get(path('apps')).data.child(request.auth.token.appid).exists()
}
function ownsExisting () {
return resource.data.uid == request.auth.uid
}
function ownsPayload () {
return request.resource.data.uid == request.auth.uid
}
function appIdInExisting () {
return resource.data.app_id == request.auth.token.appid
}
function appIdInPayload () {
return request.resource.data.app_id == request.auth.token.appid
}
}
}
/apps
有1个名为“ sample-app-id”的文档,其中“ sample-app-id”的 id 和 name 字段...在我的令牌中使用它不起作用:FirebaseError: Missing or insufficient permissions
我正在通过服务器上的此函数生成令牌:
var FirebaseAdmin = require('firebase-admin')
var serviceAccount = require('./firebase-service-credentials.json')
var claims = require('./custom-token-claims') // {appid: 'sample-app-id'}
let credential = FirebaseAdmin.credential.cert(serviceAccount)
FirebaseAdmin.initializeApp({ credential })
const generateTokenWithPayload = async id => {
try {
const token = await FirebaseAdmin.auth().createCustomToken(id, claims)
return { data: { token } }
} catch (err) {
return { error }
}
}
module.exports = async event =>
await generateTokenWithPayload(event.data.userIdentifier)
并且在发布前我要登录-我可以验证这一部分是否正常运行,因为我在firebase控制台的 Authentication-> Users 标签中看到了新的非匿名用户:
— Feb 11, 2019 Feb 11, 2019 smaple-user-id
本质上是客户端代码:
await firebase
.auth()
.signInWithCustomToken(token)
.catch(console.error)
const db = await firebase.firestore()
db.collection(path + this.state.appName).add(payload)
我正在将具有架构{app_id, app_name, date, metric, uid}
的记录发布到 sampleData / metrics / sample-app-name / {auto-generated}
要注册的应用程序数量很小-如果可能,从财务角度来看,将其设置为权限文件中的静态数组可能是有意义的,而不是< em> get 请求。
大的进步-我刚刚注意到request.auth.token.appid
应该是request.auth.token.default.appid
,因为我使用的是export default
而不是modules.export
答案 0 :(得分:0)
这个答案很好,但是可能会得到改善。
我要做的第一件事是正确识别自定义令牌中提供的有效负载-因为我正在使用云服务函数来生成有效负载(graphcool),所以我的有效负载是default: { appid }
而不是仅appid
。从那里开始,对权限进行一些重新措词就足以使用我想象中的当前规则成功验证:
service cloud.firestore {
match /databases/{database}/documents {
match /sampleData/{type}/{appName}/{record} {
allow read: if isSignedIn() && isValidApp(database) && ownsExisting() && appIdInExisting()
allow write: if isSignedIn() && isValidApp(database) && ownsPayload() && appIdInPayload()
}
// functions
function isSignedIn () {
return request.auth != null
}
function isValidApp (database) {
return exists(/databases/$(database)/documents/apps/$(request.auth.token.appid))
}
function ownsExisting () {
return resource.data.uid == request.auth.uid
}
function ownsPayload () {
return request.resource.data.uid == request.auth.uid
}
function appIdInExisting () {
return resource.data.app_id == request.auth.token.appid
}
function appIdInPayload () {
return request.resource.data.app_id == request.auth.token.appid
}
}
}
虽然有人可以做得更好。
有什么方法可以验证 appid 而不使用现有请求(也不需要编写 if-else if 链)-就像使用数组一样也许直接在规则中?
我如何确保有效载荷中指定的 appid 与我向客户端第三方应用程序发布服务凭证时所设想的相符?