nhorvath / Pyrebase4

A simple python wrapper for the Firebase API. ⛺
248 stars 61 forks source link

Pyrebase4 auth not working #33

Closed dantebarba closed 3 years ago

dantebarba commented 3 years ago

Make sure these boxes are checked before submitting your issue:

[X] Check that your version of Python is 3.4+ (3.7.10) [X] Check that you are on the newest version of Pyrebase (4.5.0) [X] Check that Email/password provider is enabled in your Firebase dashboard under Auth -> Sign In Method.

Please don't be discouraged if you do not get a response to your issue quickly, I maintain Pyrebase for fun and don't always have as much free time as I'd like.

Thank you for helping make Pyrebase better!


Unfortunately I can't login with pyrebase and get the user info. Firebase is giving 401. On the frontend, the React app does work correctly and using the request simulator from firebase it works ok too, so it's not an issue with the rules. Here is my code:

    email = post_data.get('email')
    password = post_data.get('password')
    user = pb.auth().sign_in_with_email_and_password(email, password)
    # user1 = fb_auth.verify_id_token(user["idToken"])

    # When coming back from sign in uid is localId for some reason...
    # FIXME: this line is raising 401
    user_info = pb.database().child("users").child(user["localId"]).get().val()

This are my testing rules:

{
  "rules": {
    ".read": "auth.uid != null",
    ".write": "auth.uid != null"
  }
}

Pyrebase works if rules are disabled (.write, .read both true)

This issue is already present in the old library. It seems weird that nobody noticed it because it's such a basic function. I'll probably fallback to using a service account, but that's not what I intended in the first place.

https://github.com/thisbejim/Pyrebase/issues/341

Thanks

nhorvath commented 3 years ago

auth with user and email works for me. you're using pyrebase.initialize_app(config) to get your "pb" object right?

dantebarba commented 3 years ago

auth with user and email works for me. you're using pyrebase.initialize_app(config) to get your "pb" object right?

Yes!

pb = pyrebase.initialize_app(json.load(open(os.environ["FIREBASE_CONFIG"])))

I'm testing with auth != null too, but doesn't work either. Very weird

nhorvath commented 3 years ago

the response to sign in should have localId with the uid and idToken with the token, as well as expiresIn for the token TTL

Are you saying it's only broken in tests and not for real?

nhorvath commented 3 years ago

Oh your get call doesn't pass the token!

my calls look like this db.child("dbname").child(serial).order_by_key().limit_to_last(1).get(token=self.token)

dantebarba commented 3 years ago

the response to sign in should have localId with the uid and idToken with the token, as well as expiresIn for the token TTL

Are you saying it's only broken in tests and not for real?

The other way around. When testing using the firebase request simulator it works (from inside the firebase console). When using the python app I always get 401 if security rules are enabled.

I will try with your request to see if I can manage to get something.

nhorvath commented 3 years ago

yeah try changing this line to user_info = pb.database().child("users").child(user["localId"]).get(user["idToken"]).val()

dantebarba commented 3 years ago

Ok made some progress. Now the auth object reaches the request, so with auth != null I do get authenticated. But if I try auth.localId != null or auth.uuid != null both result in 401.

dantebarba commented 3 years ago

so the auth object does reach it's destination but the way I'm calling it inside the security rule seems to be incorrect.

nhorvath commented 3 years ago

i'm not familiar with the security rules thing. you're probably not returning the auth object mapped to the correct values... unless uid is coming from your database call it's not the field name in pyrebase.

dantebarba commented 3 years ago

Solved:

user_info = pb.database().child("users").child(user["localId"]).get(user["idToken"]).val()

idk why the login token has to be provided on each request, but I will do it that way from now on.

Thanks for your help @nhorvath

nhorvath commented 3 years ago

No problem, I don't know why the original library didn't store and reuse the token. That's how I would have written it. Future enhancement perhaps some database().setToken(token) method.