This post is part 4 of a series on using OAuth with Django REST Framework. Part 2 focused on setting up your own OAuth2 server for your application, part 3 demonstrated integrating DRF with Python social auth, and part 5 is about integrating parts 1 & 2. For a summary of my thoughts on the process, see the series overview.
One point that may have been confusing from part 3 of this series is that from the social authentication standpoint, we are using the client-side, aka implicit, oauth flow. Since I'm focusing on writing a server-side Django app, that isn't very intuitive. However, when you're writing a REST API with the likes of DRF or Tastypie, and a separate front-end app (iOS, Android, JS, etc.), that is exactly what you need to be doing. Let's review the differences
Server-side oauth flow
OAuth is pretty confusing (to me at least). Many people on the internet have come up with better explanations, but here's a recap of a server-side oauth flow:
- You have a (Django) application and you want to let users sign up with Facebook. So, you, the developer, go to Facebook and sign up your Django app. You will specify something called a redirect uri. Facebook will assign your app a client id and client secret.
- Ellen Ripley comes to your site. She decides she wants to sign up using Facebook. ER clicks a button to "sign up with facebook". The button sends her on a journey.
- Specifically, the button sends her to some Facebook url that is specific to your Django app. It will look something like facebook.com/special_oauth_url/?client_id=YOUR_DJANGO_APPS_CLIENT_ID&redirect_uri=YOUR_DJANGO_APPS_REDIRECT_URI
- When Ellen arrives at that url, Facebook asks if she wants to approve your Django app. She does.
- Once she approves your app, Facebook sends her back to your Django site. How do they know where to send her? Wherever it was you specified in step 1 as your redirect uri.
- But wait, there's more! Facebook didn't just send ER back to the redirect uri. They sent her back with extra info. The url facebook sent her to will look something like: www.yourdjangoapp.com/special_redirect_uri/EXTRA_INFO_FROM_FACEBOOK, where the extra info contains an authorization code.
- Your Django app will take that extra info and go to another facebook url. This will look something like: facebook.com/GIVE_ME_ELLENS_ACCESS_TOKEN, and it will pass the extra info from step 6 back to facebook. Essentially you trade the authorization code for an access token.
- If everything has gone well so far, facebook will respond with ER's access token! This is it, this is what you've been waiting for. The access token is exactly what it sounds like -- it gives you access to ER's info. Now if you want to get some of ER's info (email address, profile picture), or do something on her behalf (make a post), you can do it with the access token.
Most of the oauth explanations I've read have focused on this flow. Let's take a look at a client-side (implicit) auth flow now.
Client-side oauth flow
Since both flows get you to the same eventual place (an access token) you may be wondering why to use one versus the other. It's really about where you want the code for steps 2-6 to live. In a mobile app, it makes most sense for that to be in the mobile app. You could do it all server-side if you decided to embed a webview in your app. Similarly, a web app could use a JS front-end, or you could go with a more traditional app using all Django templates, and then you would use the server-side flow.
Using the access token
Now you have an access token, what are you supposed to do with it? Save it! Once your front-end receives the access token, you should pass that to the server to be associated with a user in your database. You will use this access token to request user data from the social service in the future. If you don't save the token, or when the token expires, the user will have to go through the process again to get a new token. So, to be clear, in part 3 of this series, the entire authentication flow takes place client-side. The work that python social auth is handling is:
- Retrieving user data
- Saving the user's social associations and access tokens
- Utilities to prevent multiple users from being associated with the same social user, automatically generate a username, associate a social authentication with a user with the same email address, etc.
Baylee Feore is a Yeti Alum. At Yeti, she builds server-side APIs and web and mobile front-ends for applications. She is a former management consultant who decided to leave it all and attend a programming bootcamp. Outside of work, Baylee serves on the Board of Directors of Out for Undergrad, a non-profit that helps high-achieving LGBT undergrads reach their full potentials in their careers. Follow Baylee on Twitter.