Search code examples
djangogoogle-authenticationdjangae

Djangae Gauth integration


I'm following the "Gauth authentication" portion of Djangae's documentation but I'm running into some unexpected behavior.

I've configured urls.py and settings.py as specified by the documentation (the current settings are mostly a result of using the Djangae Scaffold) but at no point are users prompted to authenticate using or link their Google account. I've tried un/setting DJANGAE_CREATE_UNKNOWN_USER but this has no impact.

I've also tried running commands inspired by sitepackages/prod/djangae/contrib/gauth/tests.py in my local shell in order to verify that the back-end configuration is correctly configured and that users can actually be authenticated against AppEngineUserAPIBackend but that fails because my User model (djangae.contrib.gauth_datastore.models.GaeDatastoreUser) seems to be missing required attributes: AttributeError: 'GaeDatastoreUser' object has no attribute 'user_id'.

So, am I misunderstanding how this is all supposed to work and must take some additional steps to get Google Sign-In working? Or have I (likely) misconfigured my application? (I'm happy to include genericized versions of my config, but as I said, they've come directly from Djangae Scaffold or the documentation.)

UPDATE: Interestingly, if I remove the --headless flag from my Behavior suite config, I see the expected behavior. The browser (Chrome) is being redirected to https://accounts.google.com/Login?continue=http%3A%2F%2Flocalhost%3A8080%2F

Environment:

Djangae (0.9.11)

Django (1.11.19)


Solution

  • It turns out that this is the expected behavior. In the local sandbox, users are prompted for an email address and (by default) a "user" is created for them and they are automatically logged in.

    From App Engine's "Users Python API Overview" document:

    Google accounts and the development server

    The development server simulates the Google Accounts system using a dummy sign-in screen. When your application calls the Users API to get the URL for the sign-in screen, the API returns a special development server URL that prompts for an email address, but no password. You can type any email address into this prompt, and the app will behave as if you are signed in with an account with that address.

    The dummy sign-in screen also includes a checkbox that indicates whether the dummy account is an administrator; that is, whether the account has the the Viewer, Editor, or Owner primitive role, or the App Engine App Admin predefined role. If you check this box, the app will behave as if you are signed in using an administrator account.

    Similarly, the Users API returns a sign-out URL that cancels the dummy sign-in.

    The unique ID for a User object in the development server is calculated from the email address. Two unique email addresses always represent two unique users in the development server.

    Personally, I think this design is very flawed. I don't know what Google thinks about the Twelve Factor manifesto, but this behavior is a flagrant violation of article 10 (Dev/Prod Parity), which is summarized as "Keep development, staging, and production as similar as possible". I see no reason why the full auth/redirect flow wouldn't work in the local sandbox and, at the very least, users should be able to opt into it. (I would love to find out that this is an option.)

    The most concerning part about this conditional behavior is that the user object's API is different, which is why I was seeing the error mentioned in my question ('GaeDatastoreUser' object has no attribute 'user_id'). The local user also has no nickname method.