Pregunta

My security rules look like this:

{
  "rules": {
    ".read": false,
    ".write": "auth.user != null && newData.child('user').val() == auth.user"
  }
}

Essentially, nobody (except admin users) can read, and users can only write if they supply the same "user" key as when they authenticate.

In the Firebase simulator, everything works correctly. No reads, only correctly authenticated writes:

Attempt to write {"data":"Some Data","user":"testuser1"} to / with auth={"user":"testuser1"}
/:.write: "auth.user != null && newData.child('user').val() == auth.user"
    => true

Write was allowed.

Here's my code (node.js):

var FirebaseTokenGenerator = require("firebase-token-generator");
var tokenGenerator = new FirebaseTokenGenerator(FIREBASE_SECRET_TOKEN);

var Firebase = require('firebase');
Firebase.enableLogging(true, true);

var userID = "testuser1";

var client = new Firebase(FIREBASE_URL);
var clientToken = tokenGenerator.createToken({user: userID});

client.auth(clientToken, function(error){
if (error){
    console.log("Client login failed")
} else {
    console.log("Client login success");

    client.push({user: userID, data: "Some Data"}, function(error){
        if (error){
            console.log("Write Error: " + error);
        } else {
            console.log("Write success");
        }
    });
}
});

The strange thing here is that, on client.push I receive a Permission Denied error from Firebase.

Here's what the Firebase library prints to the log when logging is enabled:

$ node client.js 
p:0: Browser went online.  Reconnecting.  
p:0: Authenticating using credential: [object Object]  
p:0: Making a connection attempt  
c:0:0: Connection created  
c:0:0:0 Websocket connecting to wss://FIREBASE_URL/.ws?v=5  
c:0:0:0 Websocket connected.  
c:0:0: Reset packet received.  New host: REDACTED.firebaseio.com  
c:0:0: Shutting down all connections  
c:0:0:0 WebSocket is being closed  
c:0:0:0 Websocket connection was disconnected.  
c:0:0:1 Websocket connecting to wss://REDACTED.firebaseio.com/.ws?v=5&ns=REDACTED
c:0:0:1 Websocket connected.  
c:0:0: Realtime connection established.  
p:0: connection ready  
p:0: {"r":1,"a":"auth","b":{"cred":"REDACTED_TOKEN"}}  
p:0: from server: {"r":1,"b":{"s":"ok","d":{"auth":{"user":"testuser1"}}}  
Client login success
r:0: set {"path":"/-JMaX2bT9IcgrN1uPBOK","value":{"user":"testuser1","data":"Some Data"},"la":null}  
p:0: {"r":2,"a":"p","b":{"p":"/-JMaX2bT9IcgrN1uPBOK","d":{"data":"Some Data","user":"testuser1"}}}  
c:0:0: sending ping on primary.  
c:0:0: Primary connection is healthy.  
p:0: from server: {"r":2,"b":{"s":"permission_denied","d":"Permission denied"}}  
p:0: p response {"s":"permission_denied","d":"Permission denied"}  
FIREBASE WARNING: set at /-JMaX2bT9IcgrN1uPBOK failed: permission_denied 
Write Error: Error: PERMISSION_DENIED: Permission denied

What am I doing wrong? Why am I getting different responses from the Simulator and my code?

¿Fue útil?

Solución

Typical - now I've posted the question to StackOverflow, I manage to figure it out.

Here are my new security rules - the client code remains unchanged:

{
    "rules": {
        ".read": false,
        ".write": false,
        "$": {
          ".read": false,
          ".write": "auth.user != null && newData.child('user').val() == auth.user",
        }
    }
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top