Django and Google OAuth — limiting to certain users

I recently started a Django project that used django-allauth to perform authentication based on Google accounts. One problem I encountered was how to limit who can actually log into the site. I didn’t want anyone with a Google account to be able to log in!

Google’s API does have provisions to limit only certain users from passing the authentication, but it only works during the testing phase of your API. The feature wasn’t meant for production, and is limited to 100 users. On top of that, I wanted my Google API to be a set-and-forget experience. I didn’t want the inconvenience of having to log into my Google API console just to allow a new user — there had to be a way to do it on the Django side.

The solution wasn’t that complicated at all, and I wanted to share it here in case it helps anyone else.

In your settings.py, add a line for ALLOWED_EMAILS:

# ... all your other settings.py stuffALLOWED_EMAILS=[
'none@none.com',
'example@example.com',
'me@me.com',
]

Basically, all you want to do is check the request.user.email against this list.

How I chose to implement it:

It’s probably easier to digest from bottom-to-top. The @user_passes_test(email_check) decorator will only allow users whose emails match ALLOWED_EMAILS to view the index view. Otherwise, it kicks the user back to the login view (more on that in a second).

The email_check function basically returns true is the email is found in the list, and returns false otherwise. The split up false statements was just to make it more readable for myself. If the user is anonymous, then they won’t have user.email and so I’m trying to catch that case before a “field does not exist” error is thrown. There are probably more Pythonic ways to do it — feel free to tell me yours in the comments!

Finally, the login() view has to catch the user if they got bounced by another view (such as index). If the user got bounced back to the login view by the @user_passes_test(email_check) decorator, then they are “authenticated” (as far as Google OAuth and Django session cookies are concerned), but they are not allowed based on their email — so we generate a messages.error() to let them know. In any case (authenticated-but-bounced, or not authenticated at all), we render the login.html page with a “Login with Google” button.

I hope this helps somebody! Feel free to share any improvements or corrections in the comments!

--

--

--

Tech junkie, entrepreneur dreamer, practical engineer

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Accelerating Compilation 2.5X with Dependency Decoupling & Containerization

Docker series (part 1 of 4): Basics of Docker

Object Pooling for Unity

Hi, I’m Theerut Foongkiatcharoen

FREE: Creative Coding Classes for Beginners

How to use App Links Assistant in Android Studio 2.3

The Countdown Begins—YODASWAP DeFi Launch

KM Component 37: Search Engines and Enterprise Search

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store
Albert Liang

Albert Liang

Tech junkie, entrepreneur dreamer, practical engineer

More from Medium

Top Django Development Companies In The UK

Retrieve Twilio Call Logs Using Django

Watching webcam stream in terminal, using ascii characters & Python

Deploy Python Flask App on Heroku using Pycharm

After login, you will see overview of your profile page like this.