CodementorIO / rest-firebase

Ruby Firebase REST API client built on top of rest-core
Apache License 2.0
107 stars 22 forks source link

401 Permission Denied #3

Closed ghost closed 9 years ago

ghost commented 9 years ago

I seem to get a 401 when I use my secret key.

I expect this to work:

POST app.firebaseio.com/reference.json?auth=secret_key

However, it looks like the library re-writes the secret key and causes an auth error. Do you have a means to allow api key authentication?

Works fine when I monkey patch your generate_auth and just return the secret:

module RestFirebase::Client

  def generate_auth opts={}
    secret
  end

end

It would be very useful if there was an option to supply raw secrets without your manipulation of them, copy/pasting admin secrets from Firebase doesn't work in your default scheme.

godfat commented 9 years ago

May I ask how did you make the call? This should work:

client = RestFirebase.new(:auth => 'YOUR SECRET')
client.get('SOMETHING')

However, I would recommend use JWT for the auth instead. To use JWT, just pass your secret like this:

client = RestFirebase.new(:secret => 'YOUR SECRET')
client.get('SOMETHING')

Side note: However there's a default auth_ttl set to 82800. After 82800 seconds if you're still using the same instance, it would try to reset the auth because the same JWT is only valid within 24 hours (86400 seconds). Pass auth_ttl a false to disable this behaviour if you really want to use the secret as auth.

client = RestFirebase.new(:auth => 'YOUR SECRET', :auth_ttl => false)
ghost commented 9 years ago

Thanks-- it looks like that works. I thought auth was only true/false to enable or disable. I didn't see you could do that.

I think auth_ttl to false is a must (I have a very long running private server that is just queueing jobs in Firebase).

PS,

This implementation of the REST API is a lot better than others I have found!

godfat commented 9 years ago

Please see README for more detail, and please let me know if there's anything which isn't clear.

May I know why don't you use JWT instead? That would make your secret less likely to leak. For example, our logger could log all the network activities. Leaking JWT might be fine because it would be invalid after 24 hours, but if the secret leaks you would need to change the secret.

ghost commented 9 years ago

For simplicity at the moment, it's a private server that only writes to Firebase and the auth details are on the server itself so if it's compromised then an attacker would have means to create tokens etc. I should probably move it over to JWT anyway, since I can lock it down to writing to a specific area of Firebase I could make it a lot more secure.

godfat commented 9 years ago

I see, thanks!

In that case, you might want to create a JWT which could last long. I just realized that for now there's no easy way to setup expiration date for automatically generated JWT... For now it would be:

jwt = RestFirebase.new(:secret => 'SECRET').generate_auth(:exp => Time.now + 86400*365)
client = RestFirebase.new(:auth => jwt, :auth_ttl => false)

We should probably make this easier.

ghost commented 9 years ago

Is rest-firebase's token generation the same as the firebase_token_generator gem (https://github.com/firebase/firebase-token-generator-ruby)? I also generate tokens so if I could use rest-firebase for that as well it would get rid of another gem. I will log a task for myself at work to convert to JWT and try an shed the token generator gem if possible :)

godfat commented 9 years ago

Well, I didn't really check how they wrote it, but if they were also conforming JWT RFC, then it should give you the same result.

Good luck :)

ghost commented 9 years ago

Thanks--!