loading...
Cover image for Dancing with OAuth: a step by step guide

Dancing with OAuth: a step by step guide

anabella profile image anabella Updated on ・7 min read

Dancing with OAuth: a step by step lesson

Most of the times I try to learn something new and put it into practice, I quickly start to feel like I’m lost in a myriad of dance moves. I’m desperately trying to find the right way to do things, while not really understanding what’s going on or how I ended up on the wrong side of the room…

Just trying things out until something works.

Maybe it’s because of the way my learning process works, or maybe guides and tutorials are targeted at more experienced or technical people. But, after I’m done wrapping my head around the subject, I always feel like there should be an easy guide for understanding the key concepts and making it easier to apply them in a project.

So this time, I’ve decided to stop wishing for it and make it myself, using the last thing that I learned.

And that thing was OAuth 2.0.

What is OAuth?

Let’s start with the basics: OAuth stands for Open Authorization. It’s a process through which an application or website can access private user data from another website.

This other website usually works only as a trusted identity provider. It gives the requesting app some basic information about you so that the app can create a profile. This way, you don’t have to fill in a boring sign-up form and deal with yet another password 📋

You’ve already used this at least a gazillion times, in fact you used it every time you clicked on “Log in with Facebook / Google / GitHub / …”. Next, you were shown a consent screen that displayed which information from your (let’s say) Facebook profile you’re allowing that-hot-new-app.com to read (and sometimes, write). After that, since that-hot-new-app.com trusts the identity provided by Facebook, they can create a profile for you on their database using the data that they received.

The communication between that-hot-new-app.com and Facebook usually ends here. This is why your profile picture won’t change all across the Internet if you change it on Facebook. They just never go back to Facebook and ask for updated data.

When marimba rhythms start to play…

There’s another purpose for building this kind of mechanism, one with way more potential: using the identity provider as a service provider (in an ongoing manner). This means communicating with it regularly to supply enhanced features for your users.

A nice example of this is Relive, a service that connects with different sports tracking apps to create Earth view videos of your run or ride. Every time you finish an activity, Relive prompts you offering to create a video from it. If you say yes, they’ll process it, and notify you when it’s ready for social media bragging… I mean sharing 🏅

There’s really no technical difference between these two usages. That’s why you should be cautious about where you log in with your social media or Google/Gmail account.

It might sound scary, but there's really nothing to fear. Just bear in mind that you’re authorizing that-hot-new-app.com to access that information about you that’s detailed in the consent screen, potentially on a recurrent basis. Be aware of the permissions you grant, and make sure you know how to disable them whenever you don’t feel trusting anymore.

For instance, if you are using your Google account for accessing that-hot-new-app.com but don’t want to allow that anymore, just go to your Google account settings and disable their access.

All the main identity providers offer control over this.

Grooming it up before you hit the streets

Before you land on that-hot-new-app.com and even click on “Log in with YourFavoriteIdentityProvider”, someone — probably a developer — has to create an application on the provider’s site.

This is a way of registering that-hot-new-app.com so that, later, the provider knows who’s asking for private data.

In this step, the developer will set up some information about the application, like the app's name or website and — most importantly — a redirect URI. The provider (like Google or Facebook) will use this to contact the requesting app and tell them that the user said yes 💍

I promise you won't have to write it by hand, we pride ourselves on our paperlessness.

Once the app is registered, the provider will give that-hot-new-app.com a clientId and a clientSecret which will be used in the communications between them. They work sort of like a username and password for the registered application.

You'll get the clientID and clientSecret right after you click on Save application

It's very important that you keep your application information (redirect URIS, clientId, an especially clientSecret) in a secure location and don't share it with strangers. If someone gets access to them, they could request private user data from the provider on your behalf, and then use it for evil!

We don't want that.

Hands on waists or shoulders

Apart from setting up all those things, our developer has to find out what kind of data the provider gives access to, and how it’s segmented.

These “segments” are known as scopes and they define access rights, usually separated in read/write categories.

So, for example, that-hot-new-app.com can request for profile:read and contacts:read scopes. This means they can read whatever information the provider assigns to the “profile” and “contacts” segments, but they cannot change it. Other things won’t be accessible, for example your posts or what content you like.

Well, just to make things simple for now on, let’s say that that-hot-new-app.com is a website that integrates with Typeform, a service for creating beautiful and smart forms and also the company I work for 🤷. You definitely want in on the hottest thing right now, and quick, so on their website you click on “Log in with Typeform” to get right into the action. What’s next?

Here’s a home-made, organic, and cholesterol-free diagram to use as a map for the whole thing. It may look a bit complicated but don’t worry, we’ll examine each step up next.

Colorful notes bring joy to my heart

Authorize: the first step in the OAuth dance

So, you take the initiative and click on “Connect with Typeform”. Here, that-hot-new-app.com (THNA from now on, ’cause I’m getting tired of writing dash-separated words) will send you to Typeform’s authorize endpoint (/oauth/authorize) and provide:

  • their clientId (remember, that’s THNA’s username)
  • their desired scopes (or access rights)
  • and their redirect URI again (Typeform already knows it from when we set up the whole thing, but we send it again as an extra layer of security)

That URL will look something like this:

https://api.typeform.com/oauth/authorize?client_id=yourClientId&scope=accounts:read+forms:read+results:read

Typeform will use this information to generate a consent screen where you can review what sort of things you’re authorizing THNA to see and do.

Consent screen generation flow

Once you have thoroughly read what you’re consenting to and happily click on “Allow”, Typeform will send you to the redirect URI with a temporary, like so:

https://that-hot-new-app.com/auth/redirect?code=xxxXXXxxxXXXxxx

Token: it takes 2 to tangOAuth 💃

All this back and forth feels like someone’s taking you for a tango spin, right?

The second step of the OAuth dance is when THNA receives that code, and exchanges it for an OAuth Token.

So at this stage THNA has a temporary code that represents everything they're asking for, think of it as an encrypted way of saying:

"Hey, remember me? I'm THNA, This user said I can look at their forms and themes. When you're ready, please send me a token for that to this redirect URI."

As reward for knowing all the steps and not stepping on anyone's toes, THNA will get a shiny OAuth Token ✨ which it can use to interact with Typeform on behalf of the user (that's you!) and ask for the authorized data whenever they need it.

Stay with me, sway with me

From now on, in every request THNA makes to Typeform on your behalf, they’ll have to include an Authorization header with that access token. With it, Typeform (or any other provider) can identify:

  • who’s asking for the data (in this case, THNA)
  • who’s the data about (you!)
  • and also make sure they have the correct authorization to access that data (only what you consented to).

Ready for the dance floor 👯

So now that you know all the steps and spins of the OAuth dancing technique you should be ready to create your own choreographies, I mean, integrations, and make the Internet an even greater place.

*Drawings by yours truly


If you're looking for a deeper, more hands on experience with OAuth 2.0 I strongly recommend The Net Ninja's PassportJS tutorial. It covers all the basics you need to know to set this up (in a NodeJS app), in a very well balanced theory/practice proportion. It was the turning point for my process in understanding all of this.

Posted on by:

anabella profile

anabella

@anabella

Full-stack developer, recovering ex-QA

Discussion

markdown guide
 

tangOAuth sounds like a stellar name for a library or API. Just sayin'.

 

I'd like to see this same simple explanation of OAuth when it is app-to-app. There's not a ton of difference really, but go trying to search for a simple explanation on doing OAuth when there is no "user" there for initiating and accepting steps. I've always wanted a great way to help new devs with that -- because they always get hung up on all tutorials focusing on user instead of app-to-app.

 

Hi Anthony!

I'm a newbie myself, so I've never heard about app-to-app OAuth flows and I can't really think of how it could work.

Could you provide a simple example or use case for something like that?

Thank you in advance! :)

 

Funny, I've almost never had the need to build out a user-initiated OAuth flow. :)

The way I'd normally use app-to-app is having some server side code that needs to talk to an API like pulling down tweets from Twitter, inventory from some ecommerce API, etc. Your app has to be able to work through OAuth without the user accepting anything -- there is no user to click the button!

In the OAuth2 spec the grant type of client_credentials is what does this.

Seems simple, but a wonderful walkthrough like what you made for user auth is something I've always wanted to be able to hand off to my team when this sort of thing comes up. Often the docs for APIs we talk to just never go over client_credential flow instead of user auth flow (LOTS of them lack this documentation); so a junior member might get stuck trying to figure it out for quite a while.

It's not complicated -- if anything it is simpler than user auth. But once you get into expiring keys, re-authing, etc it could get interesting.

I really enjoyed your article. Hope to see more from you! :)

 

An issue I've come across working with people who aren't experts is educating about why tokens need to be short-lived, why we need to use refresh tokens, and that they need to modify their processes for locking down/terminating user accounts because authentication and authorization is now decoupled.

 

Hi Anton! I am definitely not an expert and would love if you could expand a bit on short lived tokens and the need for terminating accounts.

Thank you for reading!

 
 

Great article!
I have a question: How does this "dance" differ when the user is logging to THNA via the third party site (having previously signed up via that same site)
Does THNA store the oAuth token?

 

Thank you!

So, I'm not really an expert about this subject. I just wrote this based on my process of understanding how this flow works, and kept more complex things like this (or like the extra state string parameter) out of it for the sake of simplicity.

It is an interesting question, and from what I've been reading and seeing, after the first time the user logs into THNA using their Typeform account, THNA will create a profile for them and give them a cookie to know if they're authenticated in THNA. This cookie can there store an encrypted version of all the information THNA needs. So if THNA detects that cookie they know they don't need to make you authenticate again. In the case of my test oauth integration app with PassportJS, the decoded cookie looks like this ibb.co/jRbUhJ . In some implementations these auth tokens have an expiration period, so if they try to use it, Typeform will ask THNA to use a refreshToken to create a new one. I haven't explored this further, but just know it exists.

But what if I logout of THNA? then I'll have to "Log in with Typeform" again. So, actually, before THNA created a user for me on their site, they checked if they already knew me. They did this by storing some information from the provider, like my Typeform account ID (if it I consented to show them my profile). And this time, they do know me! So when THNA does the dance again, they'll recognise me, and won't create a new account, but instead show me my THNA profile using the new token they got from Typeform (remember I lost the cookie when I logged out of THNA). And since the scopes and the client (application) ID are the same, Typeform won't prompt me for consent and just provide a new one. Now THNA will create a new cookie with all the information so I can remain logged in again.

I hope this clears it up a little bit for you. If you have doubts I strongly recommend The Net Ninja's tutorial on OAuth and PassportJS. It was a turning point in my understanding of all this.

Thank you again for reading!

 

Great, thanks! I'll check that playlist
Please keep writing posts!

 

This is awesome! Thank you for the simple explanation!! I understood OAuth before, sort of, but this put it in a simple context and made it a lot easier to understand and explain to others! Great post!

 

Thank you! :D

There's definitely more depth to it, but I thought this is all you need to know to really understand what's going on. There might be a sequel with an in-depth dive someday ;)

 

Informative post to get started on OAuth. And curious about how you created note drawings.

 

I was too. It seems she actually drew them.

 

Hi! Thank you for reading! I did actually draw them with colored pens and paper. It really helps me to organize information and specially flows or multi step processes. Though doing it digitally (in illustrator for example) would be a possibility I just don't finde the same connection between my understanding and the process of building the diagram. It's the same for less draw, more texty notes for me. There's a much stronger cognitive connection with something I wrote by hand, than with something I typed or clicked into existence. Hope you liked them! :)

Good efforts and useful tips for the rest

 

I've recently been learning the OAuth journey for a few platforms and this helped solidify everything I've learned :)

 

Wow that's awesome! This was the result of me trying to figure out the OAuth flow in my company. If you want to implement something using OAuth and Node I can recommend the PassportJS tutorial by The Net Ninja, which was perfect for me as a starting point. Happy integrating!!! :D

 

We're adding oauth sign in to our Laravel app and performing actions on behalf of those users. But I've used PassportJS and it's great!

 

Great Read! This is a great start for someone who is looking to implement OAuth in their application. Keep up the great work!

 
 

The graph describes how OAuth works between THNA and Typeform is amazing!! It's the best explaination about OAuth I've ever seen. Keep it up!!!

 

You're a great teacher! Thank you for sharing. I especially like your hand drawn illustrations! :)

 
 

Pretty awesome and easy to understand post. :D