Firebase Storage Rules with Custom Claims

徘徊边缘 提交于 2019-12-01 11:09:36

If I'm not wrong you are using this wrong. Should be:

service firebase.storage {
  match /b/{bucket}/o {
    match /{environment}/{client_id}/{allPaths=**} {
      allow read: if request.auth.uid == client_id
    }
  }
}

The token returns others objects, like:

  • email
  • email_verified
  • phone_number
  • name
  • sub

So for you be able to compare the user Id you must use request.auth.uid. This way will compare the cliente client id. If you want to take a look at the docs, is everything abour the request.auth.

Edit

Case you want your own custom token, like: request.auth.token.client_id, you need do that with this code in Python:

uid = 'some-uid'
additional_claims = {
    'client_id': your_custom_client_id
}

custom_token = auth.create_custom_token(uid, additional_claims)

Then you can use in your storage rules:

service firebase.storage {
  match /b/{bucket}/o {
    match /{environment}/{client_id}/{allPaths=**} {
      allow read: if request.auth.token.client_id == client_id
    }
  }
}

See the docs

Custom claims are the only way to do this right now. Rules should look like this:

service firebase.storage {
  match /b/{bucket}/o {
    function isAuth() {
      return request.auth != null && request.auth.uid != null
    }
    function isAdmin() {
      return isAuth() &&
      request.auth.token.admin == true;
    }
    function clientMatch(clientId) { // expects user's "client" field to be ID of client
      return isAuth() &&
      clientId == request.auth.token.clientId;
    }
    match /storage/path/{clientId}/{allPaths=**} {
        allow read, write: if isAdmin() || clientMatch(clientId)
    }

where we use two custom fields on the auth token: admin and clientId. The cloud function to sync with the db can look something like this:

exports.updateUser = functions.firestore
  .document('users/{userId}')
  .onWrite( async (change, context) => {
    // change.before and change.after are DocumentSnapshot objects
    const userid=context.params.userId // (from {userId} above)
    const isDeleted = !change.after.exists
    const isNew = !change.before.exists
    let customClaims = {}
    if (!isDeleted) {
      let newData = change.after.data()
      let oldData = change.before.data()
      // do we need to update anything?
      if (isNew ||
          newData.admin !== oldData.admin ||
          newData.client !== oldData.client) {
        customClaims.admin = Boolean(newData.admin)
        customClaims.clientId = newData.client
      }
    }
    else {
      let oldData = change.before.data()
      customClaims.admin = false
      customClaims.clientId = null
    }
    // now do the update if needed
    if (customClaims !== {}) {
      // See https://firebase.google.com/docs/reference/admin/node/admin.auth.Auth
      await admin.auth().setCustomUserClaims(userid, customClaims)
      console.log(`Updating client for ${isNew?"new":"existing"} user ${userid}: ` +
                  `${JSON.stringify(customClaims)}`)
    }
  })

That runs on any change to the user document, and syncs it to the auth's custom claims.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!