Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Client doesn't have permission to access the desired data. #56

Closed
irohitb opened this issue May 11, 2019 · 20 comments
Closed

Client doesn't have permission to access the desired data. #56

irohitb opened this issue May 11, 2019 · 20 comments

Comments

@irohitb
Copy link

irohitb commented May 11, 2019

Hey, I am getting following error

Error: permission_denied at /flamelink/environments/production/schemas/user: Client doesn't have permission to access the desired data.

I am using cloud fireststore instead of firebase and I have a feeling that I followed the doc correctly, anway my rules for the cloud firestore (from the docs are)

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth.uid != null;
    }
  }
}

What I was trying to do

import app from "./../config/firebase"
 const usernameExsist = await app.content.get('user', { id: username })

Yes I did initialise the app like this

import * as firebase from 'firebase';
import flamelink from 'flamelink';

const keys = {
   //web credentials from web
}

const firebaseApp = firebase.initializeApp(keys);
const app = flamelink({ firebaseApp });
export default app;

Any idea what I could be doing wrong?

@jperasmus
Copy link
Contributor

Hi @irohitb thanks for creating this issue. This SDK only supports the Realtime Database and is the reason for the error you are seeing. Good news is that we have a new JavaScript that handles both the RTDB as well as Cloud Firestore. The documentation for it is here.

Do bear in mind that the new SDK is currently in alpha and even though we do not plan to make any more breaking changes, it is totally possible that we would need to make them without notice.

@ngmiduc
Copy link

ngmiduc commented Jun 29, 2019

Hi,

your problem is that your web app or whatever needs to be initialized and !! authorized to read the data:

allow read, write: if request.auth.uid != null;

that means that you can only read the documents if you have an auth.id that is your need to log in with whatever method you are using.

@ngmiduc
Copy link

ngmiduc commented Jun 29, 2019

I was wondering if using flamelink to manage the data for a public website, what would be the best or common way to allow the public to read the data.

If using

allow write: if request.auth.uid != null;
allow read: if true;

firebase service will email you that your database rules are unsecured and everyone can read the complete database. I don't know if this a problem actually since all the data will be rendered to the website anyway ... anyone else dealing with that?

@grandadmiralmcb
Copy link

grandadmiralmcb commented Jun 30, 2019

@ngmiduc It's probably best practice to have at least a client-level of credentials to access your data. In other words have a client id that your clients connect with so you can track which clients are generating your traffic. This is different from authenticating users, now you can have anonymous users but authorized applications. The best practice around his however would be to utilize a server generated frontend so that the data can be pulled using a secret key from the server instead of exposing sensitive keys to the user's browser and then subsequently embedded the rretrieved data in the output sent to the users.

@grandadmiralmcb
Copy link

grandadmiralmcb commented Jun 30, 2019

@ngmiduc In this manner then you could completely privatize your data and only have public apis with generated access keys to access your data from the public domain so you can throttle accounts based on usage.

@jperasmus
Copy link
Contributor

Thanks for your insightful answers @ngmiduc and @grandadmiralmcb

To add to the discussion:

@ngmiduc You do not have to either be authed or not, you can customize your database rules so that certain content is readable without being authed, while you lock your other content down to either no access from your app's front-end or for specific UID's, etc.

Here is an article I wrote a while back for the real-time DB, but the same principals can be applied for Cloud Firestore as well.

To @grandadmiralmcb's point, you can also consider using Firebase's anonymous auth.

@ngmiduc
Copy link

ngmiduc commented Jul 1, 2019

Hey, thanks for the extra information.
I was wondering how the equivalent rule would be for the Cloud Firestore to provide access to anyone for nonsensitivedata, like the rule for RTDB:

{
  "rules": {
    "flamelink": {
      ".read": "auth != null",
      ".write": "auth != null",
      "users": {
        ".indexOn": ["email"]
      },
      "environments": {
        "$environment": {
          "content": {
            "nonSensitiveContentType": {  
              ".read": true  
            }
          }
          "schemas": {
            ".read": true
          }
        }
      }
    }
  }
}

Thanks, best.

@jperasmus
Copy link
Contributor

Like I'm sure you already are well aware, in Firestore, we store all your content in a single collection called fl_content. This means, if you want to only open up some of the documents because they are considered non-sensitive, you can use Firestore's resource queries to check the schema metadata property. Something like this (using blogPosts as an example):

match /fl_content/{document} {
   allow read, write: if isNotSensitive() || isAuthed();

   function isNotSensitive() {
      return resource.data._fl_meta_.schema == "blogPosts";
   }

   function isAuthed() {
      return request.auth.uid != null
   }
}

@ngmiduc
Copy link

ngmiduc commented Jul 2, 2019

Hi, yes I noticed that. Thanks for the code.
I have tried the code with the new flamelink SDK in alpha and I still struggling in not having the right permissions.

FirebaseError: [code=permission-denied]: Missing or insufficient permissions.

from :

    "firebase": "^6.2.0",
    "flamelink": "^1.0.0-alpha.19"

Firestore rules:

service cloud.firestore {
  match /databases/{database}/documents {
    match /fl_content/{document} {
       allow read, write: if isNotSensitive() || isAuthed();
       function isNotSensitive() {
          return resource.data._fl_meta_.schema == "content";
       }
       function isAuthed() {
          return request.auth.uid != null
       }
    }
  }
}

I have the feeling that flamelink wants to access also to all other collections in firestore. llike: fl_files, fl_folders ... and so on. I feel like that I have to permit the web app and flamelink access to all flamelink collecitons: fl_content/enviroment/files/folders/locals/permission/user/schemas/settings.

So maybe just use firebase anonym. login

@jperasmus
Copy link
Contributor

Oh ya, I meant to give the permissions as an example for the fl_content collection, if you have some documents that should be accessible to all users without a login.

For the app itself, Flamelink requires read and write permissions for all the Flamelink specific collections (starting with fl_) for the specific user logged in. To quickly get started we suggest setting basic read and write permissions for authed users, but the idea is that this should be customized for each project as needed. What you could do is only allow write permissions for your specific user that will be logging into the Flamelink backend and managing the content and then open the specific content to read for anyone regardless of authentication status.

Are you seeing this permission denied error within Flamelink or your app? If it is your app, there is also a precache option enabled by default for performance reasons that will read from fl_schemas, so you might need to open that for unauthed access as well or remove the precache option - set it to precache: false.

@ngmiduc
Copy link

ngmiduc commented Aug 10, 2019

Hi,
yes, that I was also thinking to do. I opened writing permissions to the flamelink User and I try to open up the fl_content to everyone / public. I have tried to use the example above that allows read to specific schemes and at the end, I still get no permission on ClientSide.

service cloud.firestore {
  match /databases/{database}/documents {
    match /fl_content/{document} {
    	allow write: if request.auth.uid != null;
        allow read: if isNotSensitive();
       
       function isNotSensitive() {
          return resource.data._fl_meta_.schema == "myData";
       }
    }
  }
}

flamelink:

const app = flamelink({
  firebaseApp,
  dbType: "cf", 
  env: "production", 
  locale: "en-US", 
  precache: false 
})

I have updated to alpha.21

error :

index.cjs.js?e89a:352 Uncaught (in promise) FirebaseError: Missing or insufficient permissions.
    at new FirestoreError (webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:352:28)
    at JsonProtoSerializer.fromRpcStatus (webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:14802:16)
    at JsonProtoSerializer.fromWatchChange (webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:15293:44)
    at PersistentListenStream.onMessage (webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:11280:43)
    at eval (webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:11209:30)
    at eval (webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:11249:28)
    at eval (webpack-internal:///./node_modules/@firebase/firestore/dist/index.cjs.js:1630:20)

when I try to call app.content.get() ...

@jperasmus
Copy link
Contributor

Does it work if you change the read permission to true so that anyone can read?

@ngmiduc
Copy link

ngmiduc commented Aug 12, 2019

Yep, this will work.
I just get a lot of Firebase Emails that tell me:
"hello, your firebase rules contain insecure rules ..."
and they send me that email every week.
That's why I was wondering if they could be a way around of setting read to true.

@jperasmus
Copy link
Contributor

Yes, to be clear, I do not advise that you set and leave your whole database to read: true, I just wanted to rule out everything else.

Can you please send me your whole DB rule config so that I can take a look?

@ngmiduc
Copy link

ngmiduc commented Aug 13, 2019

It is the minimum example above :

service cloud.firestore {
  match /databases/{database}/documents {
    match /fl_content/{document} {
    	allow write: if request.auth.uid != null;
        allow read: if isNotSensitive();
       
       function isNotSensitive() {
          return resource.data._fl_meta_.schema == "myData";
       }
    }
  }
}

@jperasmus
Copy link
Contributor

Flamelink itself (the app) won't work with these settings because it won't be able to access the collections.

I'm not 100% sure about your app's use case, but what I would suggest is to use something like this:

service cloud.firestore {
  match /databases/{database}/documents {
    allow read, write: if isCmsUser();

    match /fl_content/{document} {
       allow read: if isNotSensitive();
       
       function isNotSensitive() {
          return resource.data._fl_meta_.schema == "myData";
       }
    }

    match /fl_schemas/{document} {
       allow read: true;
    }

    function isCmsUser() {
      return request.auth.uid == "<your user's uid here>"
    }
  }
}

Depending on the API methods you use, you might need to add specific match rules for them.

@ngmiduc
Copy link

ngmiduc commented Aug 13, 2019

Let's say we are talking about a public website, e.g. a Blog where the blog posts are managed by flamelink. So the public needs to access to all blog posts / content that contain only texts, some meta infos and maybe some images. So read and write is set for the CMS user and the scheme key "posts" needs to be readable for public.

I ll try your suggestion.
Thanks

@ngmiduc
Copy link

ngmiduc commented Aug 29, 2019

Well that works very fine!
There is just flamelink blaming that it doesnt have permission to write and read.
So I needed to add:

    match /{document=**} {
      allow read, write: if cmsuser();
    }

@jperasmus
Copy link
Contributor

Great, I'm glad you got it sorted in the end.

@ferhatiltas
Copy link

Hey, I am getting following error

Error: permission_denied at /flamelink/environments/production/schemas/user: Client doesn't have permission to access the desired data.

I am using cloud fireststore instead of firebase and I have a feeling that I followed the doc correctly, anway my rules for the cloud firestore (from the docs are)

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth.uid != null;
    }
  }
}

What I was trying to do

import app from "./../config/firebase"
 const usernameExsist = await app.content.get('user', { id: username })

Yes I did initialise the app like this

import * as firebase from 'firebase';
import flamelink from 'flamelink';

const keys = {
   //web credentials from web
}

const firebaseApp = firebase.initializeApp(keys);
const app = flamelink({ firebaseApp });
export default app;

Any idea what I could be doing wrong?

Deleting and reinstalling the google service json files for android and ios will solve the problem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants