Firebase Storage Rules with Custom Claims

前端 未结 3 1821
既然无缘
既然无缘 2021-01-15 11:05

I am unable to get Firebase Storage work with custom rules and using custom claims.

In my Python Admin panel, I do the following to create the user and assign a clai

相关标签:
3条回答
  • 2021-01-15 11:25

    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

    0 讨论(0)
  • 2021-01-15 11:35

    For completeness, one need to create a token before setting the token for the user.

    Thus full code:

    uid = 'some-uid'
    additional_claims = {
        'client_id': your_custom_client_id
    }
    
    # First time, only once needed
    custom_token = auth.create_custom_token(uid, additional_claims)
    
    # Then
    auth.set_custom_user_claims(uid, additional_claims )
    
    0 讨论(0)
  • 2021-01-15 11:36

    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.

    0 讨论(0)
提交回复
热议问题