self.auth.get_user_by_password raises InvalidAuthIdError when trying to log in user after account creation

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

  •  15-10-2022
  •  | 
  •  

Domanda

In my handler for signing up users I have the bit of code as below:

success, info = self.auth.store.user_model.create_user(
                "auth:" + username,
                password_raw = password)
if success:
    self.auth.get_user_by_password("auth:" + username, password)

The username is obtained earlier in the handler from request's POST parameters.

User supplies valid username (one that doesn't exist yet), valid password, this code gets executed and it always results in auth.InvalidAuthIdError(). When I check the datastore I can see that a user has been created with the specified auth id.

I have spent a lot of time troubleshooting this and there is one aspect of this that is extremely puzzling. If I know in advance that I will submit the signup form for user with username equal to "someusername" and hardcode this username into get_user_by_password like this:

self.auth.get_user_by_password("auth:someusername", password)

This seems to log the user in properly and the InvalidAuthIdError doesn't get raised. I have no clue how to proceed troubleshooting this further... How can "auth:someusername" differ from "auth:" + "someusername"??

This is the traceback that I get:

Traceback (most recent call last):
  File "/home/radek/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 1536, in __call__
    rv = self.handle_exception(request, response, e)
  File "/home/radek/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 1530, in __call__
    rv = self.router.dispatch(request, response)
  File "/home/radek/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 1278, in default_dispatcher
    return route.handler_adapter(request, response)
  File "/home/radek/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 1102, in __call__
    return handler.dispatch()
  File "/home/radek/prasowalnia/main.py", line 44, in dispatch
    super(BaseHandler, self).dispatch()
  File "/home/radek/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 572, in dispatch
    return self.handle_exception(e, self.app.debug)
  File "/home/radek/google_appengine/lib/webapp2-2.5.1/webapp2.py", line 570, in dispatch
    return method(*args, **kwargs)
  File "/home/radek/prasowalnia/main.py", line 199, in post
    self.auth.get_user_by_password("auth:"+username, password)
  File "/home/radek/google_appengine/lib/webapp2-2.5.1/webapp2_extras/auth.py", line 459, in get_user_by_password
    silent=silent)
  File "/home/radek/google_appengine/lib/webapp2-2.5.1/webapp2_extras/auth.py", line 278, in validate_password
    return self.get_user_by_auth_password(auth_id, password, silent=silent)
  File "/home/radek/google_appengine/lib/webapp2-2.5.1/webapp2_extras/auth.py", line 150, in get_user_by_auth_password
    user = self.user_model.get_by_auth_password(auth_id, password)
  File "/home/radek/google_appengine/lib/webapp2-2.5.1/webapp2_extras/appengine/auth/models.py", line 298, in get_by_auth_password
    raise auth.InvalidAuthIdError()
InvalidAuthIdError

EDIT: This is extremely bizarre but if I modify the code to:

if success:
    time.sleep(1)
    self.auth.get_user_by_password("auth:"+username, password)

everything works, no error is thrown.

EDIT: Something is amiss as if I modify the code to:

if success:
    counter = 0
    while True:
        try:
            counter += 1
            self.auth.get_user_by_password("auth:"+username, password)
        except:
            continue
        else:
            break
    self.write(counter)

I get counter a little bit above or below 20. What would be the way to approach this in production? Should I expect that self.auth.store.user_model.create_user() can return without the creation of user actually completing in the datastore? Should I be making this assumption for any put() I issue against the datastore? If anyone with shed any light on this that would be greatly appreciated! Thank you!

EDIT: Read a bit on this and I am guessing that I am facing this issue due to "eventually consistent queries". I could possibly get the key of the new user from info returned by the create_user method but webapp2 doesn't seem to offer a way of retrieving a user by its key in the Datastore.

È stato utile?

Soluzione

The below should deal with the issue brought forth by eventual consistency.

success, info = self.auth.store.user_model.create_user("auth:" + username,
                                                       password_raw = password)
if success:
    self.auth.set_session(self.auth.store.user_to_dict(info), remember=True)

It should log in the user without querying the ndb. As I am new to webapp2 will see how this works out and if there are any issues will add information here.

I have been following the blog post here: http://gosurob.com/post/20024043690/gaewebapp2accounts though not sure how come anyone else hasn't experienced the same issue as me.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top