OAuth
Delegating username/password authentication to Github, Facebook, Google, etc.
What is OAuth, and why do we need it?
If you’ve ever seen a webapp that allows you to “Login with Facebook”, “Login with Google”, etc. as in the images below, then you’ve seen an example of a webapp that is probably using OAuth.
OAuth allows one web application to delegate the function of “username/password” checking, and account management (creating, updating, verifying and deleting accounts) to some other service, such as Google, Facebook, Github, Twitter, etc.
These other services are called OAuth Providers and the webapp that users the service is called an OAuth Client.
The version of OAuth (as of Summer 2017, when this lesson is being written) that is most current and should be used for new applications is OAuth2.
Why not implement a username/password account feature from scratch?
You could do that. This article explains an approach to implementing do-it-yourself account creation (usernames, passwords, email verifiction, password reset, etc.) using Flask and an SQL database: http://exploreflask.com/en/latest/users.html.
HOWEVER, that would take a considerable investment of time,
and after many hours of work, basic login/logout would still be the only thing your webapp would be able to do.
It is a classic case of “reinventing the wheel”.
For something that is a “commodity feature” like account management, it often makes sense to
use an off-the-shelf already implemented solution, rather than reinventing it from scratch.
Using Github, Facebook, Google etc. means that we do NOT have to spend time on a long list of necessary
features such as changing passwords, creating accounts,
verifying accounts, enforcing password restrictions, a “forgot my password” mechanism, etc. The OAuth provider
has done all of that for us, and we get to just ride for free on their work.
Do I even need user logins in my project for this course?
Maybe—maybe not. There is a below section that will ask a few questions to see whether you need authentication (user login/logout functionality) or not. It will also check to see what level of user authentication you might need.
There are a few simple questions to determine whether your web app needs user logins or not
- Do you need to save any information between sessions?
- If the answer is yes, then that means your web app will need a Database.
- And if you need a database, you’ll need user logins, so you’ll need OAuth
- This is true even if you don’t think you need to save any particular information about individual users.
- The reason has to do with security and accountability. Any webapp that let’s users upload content without authentication quickly becomes a cesspool of spam, left by bots and trolls.
- Requiring logins—and tracking which users have uploaded which content—gives you some degree of control over this.
- It doesn’t entirely prevent abuse, but it does slow down the process, and give you some way to ban specific abusive accounts.
- An even better way is to require not only a login, but an “approved” account.
- The sample code we are providing shows a particular way of doing this, levering the Github organization feature. More on that later.
- Do you want users to be able to save personalized information and preferences on your site?
- If the answer is yes, then you’ll need user logins, so you’ll need OAuth
- You’ll also need a database of some kind in which to store those user preferences.
- While your app will not be storing the username/password information, your app will update a a table/dictionary of users, keyed by the username.
- Each time a user logs in, you’ll be told by the OAuth provider what that user’s login username is; you’ll look up the user in that table. If that user doesn’t already exist, you’ll create a new entry in the table for that user.
- Is your application one that can
- give answers entirely based on information the user enters during a single session of use, AND
- does NOT need to remember anything from one session to the next (only from one page to the next), AND
- respond to user queries based on information that is either freely available online with no authentication, OR can be hard-coded in a static file that you keep with your application?
If so, then you probably do NOT need user logins, or OAuth. You don’t need to read the rest of of this page. But there are very few webapps for which that is true.
We’ll use Github as our OAuth provider, at least initially
If you do need user authentication, I highly recommend using OAuth based on Github as the way to proceed, at least initially. You can switch to Facebook, Google, Twitter, etc. or add them as additional options later if you so choose. (There is section below that explains why we are using Github as our initial OAuth provider below.)
Why Github as our OAuth provider?
Here’s why we are using Github as the OAuth provider for our sample applications:
- Everyone in this course has a github account, so everyone in this course will be able to test your application
- Github does not require you to put in a real first and last name associated with your account. That way, students in this class can retain their privacy, which is important for ethical, social, and legal reasons. (By contrast, Facebook and Google require you to put in your real name, so they may not be appropriate OAuth providers for our applications in this course.)
- For certain applications, we can use the class organization,
ucsb-sbhs-cs
as a way to further restrict logins only to people that are students in the class or otherwise associated with the SBHS CS Academy. - Focusing on a single provider for our initial documentation of the process makes things much easier.
- The instructional staff has more experience with Github’s OAuth system than with the other OAuth providers out there.
Example code:
Below are two example repos with code for using OAuth Authentication with Github in a Flask Applicaiton.
Each of the repos below requires a bit more explanation—the code won’t just “run” without these important configuration steps:
- Creating a client_id and client_secret specific to your instance of this application.
- You have to do this from scratch each time you move the application to a different host or port number
- That means you have to do this step once for running on your local machine (e.g.
http://127.0.0.1:4000
and a second time if/when you run on Heroku - Instructions for creating those are here: Github OAuth Setup
- Putting the client_id and client_secret, along with perhaps other configuration, into either:
- an appropriate
env.sh
file (if running locally on ACMS or your own computer), OR - the Heroku Config Vars screen (if running on Heroku)
- Adding an explanation of these two steps to the website is still a TODO ITEM.
- In the meantime, an instructor or mentor may be able to walk you through it.
- an appropriate
Here are the code examples:
TODO: Update these links to repos
- Simple github oauth: https://github.com/ucsb-sbhs-cs/webapps-oauth-example
- If you have a github account, you can log in.
- This app only works with sessions; no connection to a database
- No ability to store user preferences, or any other persistent data
- Github OAuth based on organization membership: https://github.com/ucsb-sbhs-cs/webapps-oauth-github-org-example
- Checks is you have a github account, AND
if you are a member of specific github organization specified
by the application (e.g.
ucsb-sbhs-cs
, for example.) - Like preceding one, this app only works with sessions; no connection to a database
- No ability to store user preferences, or any other persistent data
- Checks is you have a github account, AND
if you are a member of specific github organization specified
by the application (e.g.
- Github OAuth along with MongoDB access: https://github.com/ucsb-sbhs-cs/webapps-oauth-and-pymongo-v1
- Similar to webapps-oauth-github-org-example, but also includes example of accessing a MongoDB database
Using Flask-OAuthlib
Flask-OAuthlib is a Python module that you can use to add authentication to your webapp via any OAuth provider.
In this section, we’ll discuss how to use Github as our OAuth provider, since every participant in this course has a github account.
pip install Flask-OAuthlib
First, on any system where you want to use this library, you need to install it.
pip install Flask-OAuthlib