OAuth2 is a draft standard on how to perform delegated authentication/authorization on the internet. It is already used by many popular sites like Google, Facebook, Twitter etc.
I have had a hard time understanding how OAuth2 works and why we do certain things in the process. This is a note to myself and also for anyone else who is struggling to understand how and why it works. Let's get started.
Authenticate users:Â The nice thing about this is you don't have to implement a user account management system, you get it for free from a 3rd party service (like Google).
Access user data from a 3rd party service:Â With OAuth2, users can authorize your application to access their data in another service. Your application can read/edit a user's data in their Google, Facebook, Twitter etc. accounts.
In both cases there are 3 parties involved:
Your application ("the OAuth consumer")
The 3rd party service ("the OAuth Provider") - which will authenticate the user + where you will access user data from
This post focuses on the "Access user data from a 3rd party service" part of OAuth2. The "Authenticate User" is a subset of this. Once you read the post, you will be able to figure out that part yourself (may be with some head banging - I just want to keep the post focussed). All the examples below use Google as the 3rd party service
User visits your site and wants to log in. He clicks the "Sign in with Google" button. You have specified all the resources you need permission to from his Google account.
The user is redirected to Google, where he can log into his account. Google will prompt the user if he wants to allow your application to access the requested data. After he says yes, Google will redirect the user to a page on your site along with a token that represents who he is. If he says no, Google will redirect him to a page on your application and pass an error message to you.
You can use this token to access the user's data from Google using the Google APIs.
Since access tokens represent access to user data, they are short lived for security reasons; they expire after a short period. Your application would have to get a new access token after the last one has expired to continue accessing the user data. However, once the user grants your application permissions, they will not be prompted to authorize your application again - unless the permissions were revoked.
The way the three parties (user, OAuth consumer and the OAuth provider) communicate with each other changes based on the type of application. These are referred to as different flows. I'll just focus on the two most common flows for web applications.
You would use this flow if you only need to make API calls when the user is actually on your site, i.e. if the user isn't actively using your site, you don't need to access to their data from the 3rd party service.
Here is what happens in the client side flow. I'll use Google as the 3rd party service:
User clicks "Sign in with Google". [User]
User is redirected to Google, where they authorize your application. [3rd Party Service/User]
Google redirects the user to your site with an access token in the URL hash. [3rd Party Service]
Your JavaScript code would read the access token from the hash and verify it by sending a request to Google. [Your Application]
Once the token is verified, you can make API calls sending the access token to Google to read the user data. [Your Application]
You would use this flow if you need access to the user's data even when they are not actively using your site. An example may be, your application aggregates particular posts from the user's Twitter stream. Even when the user isn't actively using your site, your application needs to do work using their data.
You may use the client side flow to do server side communication as well. Once you have the access token, you may use that token for as long as it is valid. So once you get the access token from the client side flow, you can use it on the server side.
However, there is a more secure and better suited way to use OAuth on the server side. Here is what happens in the server side flow (aka one-time-code flow):
User clicks "Sign in with Google". [User]
User is redirected to Google, where they authorize your application. [3rd Party Service/User]
Google redirects the user to your site with an access code in the URL hash. [3rd Party Service]
Your JavaScript code sends the access code to your server. [Your Application]
Your server sends the access code to Google and gets an access token and a refresh token. This access code can be exchanged for the tokens only once. So even if this access code was stolen, as long as it had been used once - it is worthless to the stealer. [Your application/3rd Party Service]
Your server verifies with Google that this is a valid access token for the user and your application, and then starts using it. You may wonder why do you need to verify this is a valid access token, since you just got it. Remember this access token was exchanged for an access code. If an access code for a different application was used, you would get a valid access token - but one that does not belong to you. This is why it is important to verify the access tokens in this case. [Your application/3rd Party Service]
As you remember, the access tokens are short lived. So once the access token expires, you can go to Google with the refresh token and exchange that for a new access token. You can keep doing this till the permissions for your application are revoked. [Your application/3rd Party Service]
When an access token is stolen, another application can act as your application and access the user's resources in the 3rd party service. So it is important to ensure access tokens are handled in a secure manner and that they cannot be stolen. Here are some some security measures to protect access tokens:
Use HTTPS in all transmissions of the access token
When using HTTPS, make sure you validate the SSL certificate of the destination. If the certificate is invalid, do not proceed.
Do not store tokens in plain text cookies
Do not pass tokens in page URLS
Make the tokens short lived. This would be implemented by the 3rd party service issuing the token.
The information I have described above comes mainly from these pages. They are more in-depth and a good read once you get the high level picture from this post. You can see the actual request/response/code in the pages below. Check them out.
http://aaronparecki.com/articles/2012/07/29/1/oauth2-simplified
http://www.slideshare.net/aaronpk/an-introduction-to-oauth-2
Generic Sign in with Google (using Google as an authentication mechanism for your app)
https://developers.google.com/accounts/docs/OAuth2UserAgent
https://developers.google.com/+/web/signin/server-side-flow
https://developers.google.com/+/web/signin/client-to-server-flow
Sign in with Google (the button)
https://developers.google.com/+/web/signin/