Possibility for only currently connected (not authenticated) and admin user to read and write on certain location

StackOverflow https://stackoverflow.com/questions/16341189

  •  14-04-2022
  •  | 
  •  

Pregunta

Is there any way to write a security rule or is there any other approach that would make possible only for currently connected (not authenticated) user to write/read certain location - admin should also be able to write/read? Can a rule be written that disallows users to read of complete list of entries and let them read only entry that matches some identifier that was passed from client?

I'm trying to exchange some data between user and Node.js application through Firebase and that data shouldn't be able to read or write by anyone else other than user and/or admin.

I know that one solution would be that user requests auth token on my server and uses it to authenticate on Firebase and that would make it possible to write rule which prevents reads and writes. However, I'm trying to avoid user connecting to my server so this solution is not first option.

This is in a way session based scenario which is not available in Firebase but I have some ideas that could solve this kind of problem - if implemented before session management:

  • maybe letting admin write into /.info/ location which is observed by client for every change and can be read only by active connection - if I understood correctly how .info works
  • maybe creating .temp location for that purpose
  • maybe letting admin and connected client could have more access to connection information which would contain some connection unique id, that can be used to create location with that name and use it inside rule to prevent reading and listing to other users

Thanks

¿Fue útil?

Solución

This seems like a classic XY problem (i.e. trying to solve the attempted solution instead of the actual problem).

If I understand your constraints correctly, the underlying issue is that you do not wish to have direct connections to your server. This is currently the model we're using with Firebase and I can think of two simple patterns to accomplish this.

1) Store the data in an non-guessable path

Create a UUID or GID or, assuming we're not talking bank level security here, just a plain Firebase ID ( firebaseRef.push().name() ). Then have the server and client communicate via this path.

This avoids the need for security rules since the URLs are unguessable, or close enough to it, in the case of the Firebase ID, for normal uses.

Client example:

var fb = new Firebase(MY_INSTANCE_URL+'/connect');
var uniquePath = fb.push();
var myId = uniquePath.name();

// send a message to the server
uniquePath.push('hello world');

From the server, simply monitor connect, each one that connects is a new client:

var fb = new Firebase(MY_INSTANCE_URL+'/connect');
fb.on('child_added', newClientConnected);

function newClientConnected(snapshot) {
   snapshot.ref().on('child_added', function(ss) {
       // when the client sends me a message, log it and then return "goodbye"
       console.log('new message', ss.val());
       ss.ref().set('goodbye');
   });
};

In your security rules:

{
   "rules": {
       // read/write are false by default

       "connect": {
          // contents cannot be listed, no way to find out ids other than guessing

          "$client": {
             ".read": true,
             ".write": true
          }
       }
   }
}

2) Use Firebase authentication

Instead of expending so much effort to avoid authentication, just use a third party service, like Firebase's built-in auth, or Singly (which supports Firebase). This is the best of both worlds, and the model I use for most cases.

Your client can authenticate directly with one of these services, never touching your server, and then authenticate to Firebase with the token, allowing security rules to take effect.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top