OAuth is an open standard for sharing access to data stored on one application with another application without revealing passwords. With this simplified problem statement, I’ll explain how OAuth works.
Actors
The actors in this story are-
- User - This is an actual person.
- Resource Server (RS) - Application which has some User information or data that is needed by some other application.
- Client Server (CS) - Another application that needs access to data from Resource Server.
Overview
Let’s assume that the Resource Server has some information that is available at GET https://resource-server.com/api/users/info. Now this information is needed from the Client server which can make a REST call to RS at the url above. But this information is only visible to authorized clients. However we do not want to share the user password for RS with CS. Instead an access_token is shared with CS that will be accepted by RS.
Given a sufficiently complex string, the probability of guessing the access_token is pretty low and is secure enough for most applications.
With the OAuth flows, the problem becomes securely getting an access_token from the RS to the CS after confirmation from the User.
Flows
Various interactions between the actors are shown below
Client Server setup
Before the actual User OAuth flows happen, the Client Server is setup once with the Resource Server. A client_id and client_secret are configured between the two applications. This information is never sent to the Users (via mobile apps or browsers) but is always exchanged and validated directly between the RS and CS in the Token Exchange phase.
The Client Server is configured with the resource server authorization and token URLs. The Resource Server can optionally be configured with redirect URLs of the Client server for the flow after User login.
User Initialization
- The user performs some action on the client server where access to information from the resource server is needed.
- This triggers the User Login flow on the client server.
User Login
- The Client Server generates a random value called state. This value will need to be validated later.
- The Client Server opens the Resource Servers authorization URL with the parameters of state, client_id, redirect_uri.
- The Resource Server internally saves the client state and prompts the User to grant access to the Client Server. A login might be needed
- After successful login by the User, the RS generates a temporary token called code.
- The RS invokes the redirect_uri URL on the CS with parameter state sent before login and code.
- The CS validates that the state parameter is the same that it sent earlier to prevent spoofing. State should be a one time use token with limited expiration.
Token Exchange
- With the code, the Client Server can now request an access_token.
- Client Server makes a call to the Resource Server token URI. Parameters passed are code, client_id and client_secret.
- The Resource server validates the parameters passed and issues a token to the Client Server.
- The client_secret is known only to both the servers. The code is a token that should expire after some time and cannot be reused.
Resource API calls
The final step is the Client Server getting access to some data from the Resource Server. Using curl, the access_token is passed as part of a header like-
curl -H "Authorization: Bearer access_token" https://resource-server.com/api/users/info
The RS can then serve the resource after validation of the access_token.
Home automation examples
Client Server - Alexa and Google Home
Alexa and Google Home are examples of OAuth client servers. Both these are voice controlled clients. For integration, your application needs to act as a Resource Server and grant access to some User information or device that needs to be controlled.
The OAuth aspect is saving client information and implementing login and token URLs. Both Alexa and Google Home have defined a protocol to access resources as well.
Resource Server - Nest
Nest is an example of a Resource Server. Devices and home information known by Nest can be read and controlled by alternate clients. For integration with Nest, your application needs to act like a Client Server in the flows above. The have good documentation on OAuth configuration.
More scenarios
Refresh tokens
Access_tokens usually expire after a short period of time. Another type of token known as the refresh_token can be sent to the client which has a longer lifetime. Using the refresh_token it is possible to get new access_tokens which can be used for API calls.
Grant types
The process explained here is specific to the grant type known as authorization_code. Here both servers can privately communicate and a client_secret can be exchanged. There are also other grant types like authorization code, implicit, resource owner password credentials, and client credentials.
Scopes
The OAuth protocol allows for limited access of resources via scopes. So rather than access to all the data for a user, only limited subsets can be available based on the scope that the user allows.
Resource Server vs Authorization Server
In the specification, the Resource Server is decomposed into the Resource Server that has the resource endpoints and the Authorization Server that has the OAuth flow endpoints. Both applications are controlled by the same team. For simpler deployments, the RS and AS can be the same server with different REST endpoints.
Hope
At first glance, OAuth looks pretty hard but it’s not as complicated to implement.