{"id":839,"date":"2016-11-28T10:40:21","date_gmt":"2016-11-28T10:40:21","guid":{"rendered":"http:\/\/adriangrigoras.com\/blog\/?p=839"},"modified":"2017-11-28T10:40:58","modified_gmt":"2017-11-28T10:40:58","slug":"introduction-oauth-2","status":"publish","type":"post","link":"https:\/\/adriangrigoras.com\/blog\/introduction-oauth-2\/","title":{"rendered":"Introduction to OAuth 2"},"content":{"rendered":"<h3 id=\"introduction\">Introduction<\/h3>\n<p>OAuth 2 is an authorization framework that enables applications to obtain limited access to user accounts on an HTTP service, such as Facebook, GitHub, and DigitalOcean. It works by delegating user authentication to the service that hosts the user account, and authorizing third-party applications to access the user account. OAuth 2 provides authorization flows for web and desktop applications, and mobile devices.<\/p>\n<p>This informational guide is geared towards application developers, and provides an overview of OAuth 2 roles, authorization grant types, use cases, and flows.<\/p>\n<p>Let&#8217;s get started with OAuth Roles!<\/p>\n<div data-unique=\"oauth-roles\"><\/div>\n<h2 id=\"oauth-roles\">OAuth Roles<\/h2>\n<p>OAuth defines four roles:<\/p>\n<ul>\n<li>Resource Owner<\/li>\n<li>Client<\/li>\n<li>Resource Server<\/li>\n<li>Authorization Server<\/li>\n<\/ul>\n<p>We will detail each role in the following subsections.<\/p>\n<h3 id=\"resource-owner-user\">Resource Owner:\u00a0<em>User<\/em><\/h3>\n<p>The resource owner is the\u00a0<em>user<\/em>\u00a0who authorizes an\u00a0<em>application<\/em>\u00a0to access their account. The application&#8217;s access to the user&#8217;s account is limited to the &#8220;scope&#8221; of the authorization granted (e.g. read or write access).<\/p>\n<h3 id=\"resource-authorization-server-api\">Resource \/ Authorization Server:\u00a0<em>API<\/em><\/h3>\n<p>The resource server hosts the protected user accounts, and the authorization server verifies the identity of the\u00a0<em>user<\/em>\u00a0then issues access tokens to the\u00a0<em>application<\/em>.<\/p>\n<p>From an application developer&#8217;s point of view, a service&#8217;s\u00a0<strong>API<\/strong>\u00a0fulfills both the resource and authorization server roles. We will refer to both of these roles combined, as the\u00a0<em>Service<\/em>\u00a0or\u00a0<em>API<\/em>\u00a0role.<\/p>\n<h3 id=\"client-application\">Client:\u00a0<em>Application<\/em><\/h3>\n<p>The client is the\u00a0<em>application<\/em>\u00a0that wants to access the\u00a0<em>user<\/em>&#8216;s account. Before it may do so, it must be authorized by the user, and the authorization must be validated by the API.<\/p>\n<div data-unique=\"abstract-protocol-flow\"><\/div>\n<h2 id=\"abstract-protocol-flow\">Abstract Protocol Flow<\/h2>\n<p>Now that you have an idea of what the OAuth roles are, let&#8217;s look at a diagram of how they generally interact with each other:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/assets.digitalocean.com\/articles\/oauth\/abstract_flow.png\" alt=\"Abstract Protocol Flow\" \/><\/p>\n<p>Here is a more detailed explanation of the steps in the diagram:<\/p>\n<ol>\n<li>The\u00a0<em>application<\/em>\u00a0requests authorization to access service resources from the\u00a0<em>user<\/em><\/li>\n<li>If the\u00a0<em>user<\/em>\u00a0authorized the request, the\u00a0<em>application<\/em>\u00a0receives an authorization grant<\/li>\n<li>The\u00a0<em>application<\/em>\u00a0requests an access token from the\u00a0<em>authorization server<\/em>\u00a0(API) by presenting authentication of its own identity, and the authorization grant<\/li>\n<li>If the application identity is authenticated and the authorization grant is valid, the\u00a0<em>authorization server<\/em>\u00a0(API) issues an access token to the application. Authorization is complete.<\/li>\n<li>The\u00a0<em>application<\/em>\u00a0requests the resource from the\u00a0<em>resource server<\/em>\u00a0(API) and presents the access token for authentication<\/li>\n<li>If the access token is valid, the\u00a0<em>resource server<\/em>\u00a0(API) serves the resource to the\u00a0<em>application<\/em><\/li>\n<\/ol>\n<p>The actual flow of this process will differ depending on the authorization grant type in use, but this is the general idea. We will explore different grant types in a later section.<\/p>\n<div data-unique=\"application-registration\"><\/div>\n<h2 id=\"application-registration\">Application Registration<\/h2>\n<p>Before using OAuth with your application, you must register your application with the service. This is done through a registration form in the &#8220;developer&#8221; or &#8220;API&#8221; portion of the service&#8217;s website, where you will provide the following information (and probably details about your application):<\/p>\n<ul>\n<li>Application Name<\/li>\n<li>Application Website<\/li>\n<li>Redirect URI or Callback URL<\/li>\n<\/ul>\n<p>The redirect URI is where the service will redirect the user after they authorize (or deny) your application, and therefore the part of your application that will handle authorization codes or access tokens.<\/p>\n<h3 id=\"client-id-and-client-secret\">Client ID and Client Secret<\/h3>\n<p>Once your application is registered, the service will issue &#8220;client credentials&#8221; in the form of a\u00a0<em>client identifier<\/em>\u00a0and a\u00a0<em>client secret<\/em>. The Client ID is a publicly exposed string that is used by the service API to identify the application, and is also used to build authorization URLs that are presented to users. The Client Secret is used to authenticate the identity of the application to the service API when the application requests to access a user&#8217;s account, and must be kept private between the application and the API.<\/p>\n<div data-unique=\"authorization-grant\"><\/div>\n<h2 id=\"authorization-grant\">Authorization Grant<\/h2>\n<p>In the\u00a0<em>Abstract Protocol Flow<\/em>\u00a0above, the first four steps cover obtaining an authorization grant and access token. The authorization grant type depends on the method used by the application to request authorization, and the grant types supported by the API. OAuth 2 defines four grant types, each of which is useful in different cases:<\/p>\n<ul>\n<li><strong>Authorization Code<\/strong>: used with server-side Applications<\/li>\n<li><strong>Implicit<\/strong>: used with Mobile Apps or Web Applications (applications that run on the user&#8217;s device)<\/li>\n<li><strong>Resource Owner Password Credentials<\/strong>: used with trusted Applications, such as those owned by the service itself<\/li>\n<li><strong>Client Credentials<\/strong>: used with Applications API access<\/li>\n<\/ul>\n<p>Now we will describe grant types in more detail, their use cases and flows, in the following sections.<\/p>\n<div data-unique=\"grant-type-authorization-code\"><\/div>\n<h2 id=\"grant-type-authorization-code\">Grant Type: Authorization Code<\/h2>\n<p>The\u00a0<strong>authorization code<\/strong>\u00a0grant type is the most commonly used because it is optimized for\u00a0<em>server-side applications<\/em>, where source code is not publicly exposed, and\u00a0<em>Client Secret<\/em>\u00a0confidentiality can be maintained. This is a redirection-based flow, which means that the application must be capable of interacting with the\u00a0<em>user-agent<\/em>\u00a0(i.e. the user&#8217;s web browser) and receiving API authorization codes that are routed through the user-agent.<\/p>\n<p>Now we will describe the authorization code flow:<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/assets.digitalocean.com\/articles\/oauth\/auth_code_flow.png\" alt=\"Authorization Code Flow\" \/><\/p>\n<h3 id=\"step-1-authorization-code-link\">Step 1: Authorization Code Link<\/h3>\n<p>First, the user is given an authorization code link that looks like the following:<\/p>\n<pre class=\"code-pre \"><code>https:\/\/cloud.digitalocean.com\/v1\/oauth\/authorize?response_type=code&amp;client_id=<span class=\"highlight\">CLIENT_ID<\/span>&amp;redirect_uri=<span class=\"highlight\">CALLBACK_URL<\/span>&amp;scope=<span class=\"highlight\">read<\/span>\r\n<\/code><\/pre>\n<p>Here is an explanation of the link components:<\/p>\n<ul>\n<li><strong><a href=\"https:\/\/cloud.digitalocean.com\/v1\/oauth\/authorize\">https:\/\/cloud.digitalocean.com\/v1\/oauth\/authorize<\/a><\/strong>: the API authorization endpoint<\/li>\n<li><strong>client_id=<span class=\"highlight\">client_id<\/span><\/strong>: the application&#8217;s\u00a0<em>client ID<\/em>\u00a0(how the API identifies the application)<\/li>\n<li><strong>redirect_uri=<span class=\"highlight\">CALLBACK_URL<\/span><\/strong>: where the service redirects the user-agent after an authorization code is granted<\/li>\n<li><strong>response_type=<span class=\"highlight\">code<\/span><\/strong>: specifies that your application is requesting an authorization code grant<\/li>\n<li><strong>scope=<span class=\"highlight\">read<\/span><\/strong>: specifies the level of access that the application is requesting<\/li>\n<\/ul>\n<h3 id=\"step-2-user-authorizes-application\">Step 2: User Authorizes Application<\/h3>\n<p>When the user clicks the link, they must first log in to the service, to authenticate their identity (unless they are already logged in). Then they will be prompted by the service to\u00a0<em>authorize<\/em>\u00a0or\u00a0<em>deny<\/em>\u00a0the application access to their account. Here is an example authorize application prompt:<\/p>\n<p class=\"growable\"><img decoding=\"async\" src=\"https:\/\/assets.digitalocean.com\/articles\/oauth\/authcode.png\" alt=\"Authorization Code Link\" \/><\/p>\n<p>This particular screenshot is of DigitalOcean&#8217;s authorization screen, and we can see that &#8220;Thedropletbook App&#8221; is requesting authorization for &#8220;read&#8221; access to the account of &#8220;<a href=\"mailto:manicas@digitalocean.com\">manicas@digitalocean.com<\/a>&#8220;.<\/p>\n<h3 id=\"step-3-application-receives-authorization-code\">Step 3: Application Receives Authorization Code<\/h3>\n<p>If the user clicks &#8220;Authorize Application&#8221;, the service redirects the user-agent to the application redirect URI, which was specified during the client registration, along with an\u00a0<em>authorization code<\/em>. The redirect would look something like this (assuming the application is &#8220;dropletbook.com&#8221;):<\/p>\n<pre class=\"code-pre \"><code>https:\/\/dropletbook.com\/callback?code=<span class=\"highlight\">AUTHORIZATION_CODE<\/span>\r\n<\/code><\/pre>\n<h3 id=\"step-4-application-requests-access-token\">Step 4: Application Requests Access Token<\/h3>\n<p>The application requests an access token from the API, by passing the authorization code along with authentication details, including the\u00a0<em>client secret<\/em>, to the API token endpoint. Here is an example POST request to DigitalOcean&#8217;s token endpoint:<\/p>\n<pre class=\"code-pre \"><code>https:\/\/cloud.digitalocean.com\/v1\/oauth\/token?client_id=<span class=\"highlight\">CLIENT_ID<\/span>&amp;client_secret=<span class=\"highlight\">CLIENT_SECRET<\/span>&amp;grant_type=authorization_code&amp;code=<span class=\"highlight\">AUTHORIZATION_CODE<\/span>&amp;redirect_uri=<span class=\"highlight\">CALLBACK_URL<\/span>\r\n<\/code><\/pre>\n<h3 id=\"step-5-application-receives-access-token\">Step 5: Application Receives Access Token<\/h3>\n<p>If the authorization is valid, the API will send a response containing the access token (and optionally, a refresh token) to the application. The entire response will look something like this:<\/p>\n<pre class=\"code-pre \"><code>{\"access_token\":\"<span class=\"highlight\">ACCESS_TOKEN<\/span>\",\"token_type\":\"bearer\",\"expires_in\":2592000,\"refresh_token\":\"<span class=\"highlight\">REFRESH_TOKEN<\/span>\",\"scope\":\"read\",\"uid\":100101,\"info\":{\"name\":\"Mark E. Mark\",\"email\":\"mark@thefunkybunch.com\"}}\r\n<\/code><\/pre>\n<p>Now the application is authorized! It may use the token to access the user&#8217;s account via the service API, limited to the scope of access, until the token expires or is revoked. If a refresh token was issued, it may be used to request new access tokens if the original token has expired.<\/p>\n<div data-unique=\"grant-type-implicit\"><\/div>\n<h2 id=\"grant-type-implicit\">Grant Type: Implicit<\/h2>\n<p>The\u00a0<strong>implicit<\/strong>\u00a0grant type is used for mobile apps and web applications (i.e. applications that run in a web browser), where the\u00a0<em>client secret<\/em>\u00a0confidentiality is not guaranteed. The implicit grant type is also a redirection-based flow but the access token is given to the user-agent to forward to the application, so it may be exposed to the user and other applications on the user&#8217;s device. Also, this flow does not authenticate the identity of the application, and relies on the redirect URI (that was registered with the service) to serve this purpose.<\/p>\n<p>The implicit grant type does not support refresh tokens.<\/p>\n<p>The implicit grant flow basically works as follows: the user is asked to authorize the application, then the authorization server passes the access token back to the user-agent, which passes it to the application. If you are curious about the details, read on.<\/p>\n<p><img decoding=\"async\" src=\"https:\/\/assets.digitalocean.com\/articles\/oauth\/implicit_flow.png\" alt=\"Implicit Flow\" \/><\/p>\n<h3 id=\"step-1-implicit-authorization-link\">Step 1: Implicit Authorization Link<\/h3>\n<p>With the implicit grant type, the user is presented with an authorization link, that requests a token from the API. This link looks just like the authorization code link, except it is requesting a\u00a0<em>token<\/em>\u00a0instead of a code (note the\u00a0<em>response type<\/em>\u00a0&#8220;token&#8221;):<\/p>\n<pre class=\"code-pre \"><code>https:\/\/cloud.digitalocean.com\/v1\/oauth\/authorize?response_type=token&amp;client_id=<span class=\"highlight\">CLIENT_ID<\/span>&amp;redirect_uri=<span class=\"highlight\">CALLBACK_URL<\/span>&amp;scope=<span class=\"highlight\">read<\/span>\r\n<\/code><\/pre>\n<h3 id=\"step-2-user-authorizes-application\">Step 2: User Authorizes Application<\/h3>\n<p>When the user clicks the link, they must first log in to the service, to authenticate their identity (unless they are already logged in). Then they will be prompted by the service to\u00a0<em>authorize<\/em>\u00a0or\u00a0<em>deny<\/em>\u00a0the application access to their account. Here is an example authorize application prompt:<\/p>\n<p class=\"growable\"><img decoding=\"async\" src=\"https:\/\/assets.digitalocean.com\/articles\/oauth\/authcode.png\" alt=\"Authorization Code Link\" \/><\/p>\n<p>We can see that &#8220;Thedropletbook App&#8221; is requesting authorization for &#8220;read&#8221; access to the account of &#8220;<a href=\"mailto:manicas@digitalocean.com\">manicas@digitalocean.com<\/a>&#8220;.<\/p>\n<h3 id=\"step-3-user-agent-receives-access-token-with-redirect-uri\">Step 3: User-agent Receives Access Token with Redirect URI<\/h3>\n<p>If the user clicks &#8220;Authorize Application&#8221;, the service redirects the user-agent to the application redirect URI, and includes a URI fragment containing the access token. It would look something like this:<\/p>\n<pre class=\"code-pre \"><code>https:\/\/dropletbook.com\/callback#token=<span class=\"highlight\">ACCESS_TOKEN<\/span>\r\n<\/code><\/pre>\n<h3 id=\"step-4-user-agent-follows-the-redirect-uri\">Step 4: User-agent Follows the Redirect URI<\/h3>\n<p>The user-agent follows the redirect URI but retains the access token.<\/p>\n<h3 id=\"step-5-application-sends-access-token-extraction-script\">Step 5: Application Sends Access Token Extraction Script<\/h3>\n<p>The application returns a webpage that contains a script that can extract the access token from the full redirect URI that the user-agent has retained.<\/p>\n<h3 id=\"step-6-access-token-passed-to-application\">Step 6: Access Token Passed to Application<\/h3>\n<p>The user-agent executes the provided script and passes the extracted access token to the application.<\/p>\n<p>Now the application is authorized! It may use the token to access the user&#8217;s account via the service API, limited to the scope of access, until the token expires or is revoked.<\/p>\n<div data-unique=\"grant-type-resource-owner-password-credentials\"><\/div>\n<h2 id=\"grant-type-resource-owner-password-credentials\">Grant Type: Resource Owner Password Credentials<\/h2>\n<p>With the\u00a0<strong>resource owner password credentials<\/strong>\u00a0grant type, the user provides their service credentials (username and password) directly to the application, which uses the credentials to obtain an access token from the service. This grant type should only be enabled on the authorization server if other flows are not viable. Also, it should only be used if the application is trusted by the user (e.g. it is owned by the service, or the user&#8217;s desktop OS).<\/p>\n<h3 id=\"password-credentials-flow\">Password Credentials Flow<\/h3>\n<p>After the user gives their credentials to the application, the application will then request an access token from the authorization server. The POST request might look something like this:<\/p>\n<pre class=\"code-pre \"><code>https:\/\/oauth.example.com\/token?grant_type=password&amp;username=<span class=\"highlight\">USERNAME<\/span>&amp;password=<span class=\"highlight\">PASSWORD<\/span>&amp;client_id=<span class=\"highlight\">CLIENT_ID<\/span>\r\n<\/code><\/pre>\n<p>If the user credentials check out, the authorization server returns an access token to the application. Now the application is authorized!<\/p>\n<p><strong>Note:<\/strong>\u00a0DigitalOcean does not currently support the password credentials grant type, so the link points to an imaginary authorization server at &#8220;oauth.example.com&#8221;.<\/p>\n<div data-unique=\"grant-type-client-credentials\"><\/div>\n<h2 id=\"grant-type-client-credentials\">Grant Type: Client Credentials<\/h2>\n<p>The\u00a0<strong>client credentials<\/strong>\u00a0grant type provides an application a way to access its own service account. Examples of when this might be useful include if an application wants to update its registered description or redirect URI, or access other data stored in its service account via the API.<\/p>\n<h3 id=\"client-credentials-flow\">Client Credentials Flow<\/h3>\n<p>The application requests an access token by sending its credentials, its client ID and client secret, to the authorization server. An example POST request might look like the following:<\/p>\n<pre class=\"code-pre \"><code>https:\/\/oauth.example.com\/token?grant_type=client_credentials&amp;client_id=CLIENT_ID&amp;client_secret=CLIENT_SECRET\r\n<\/code><\/pre>\n<p>If the application credentials check out, the authorization server returns an access token to the application. Now the application is authorized to use its own account!<\/p>\n<p><strong>Note:<\/strong>\u00a0DigitalOcean does not currently support the client credentials grant type, so the link points to an imaginary authorization server at &#8220;oauth.example.com&#8221;.<\/p>\n<div data-unique=\"example-access-token-usage\"><\/div>\n<h2 id=\"example-access-token-usage\">Example Access Token Usage<\/h2>\n<p>Once the application has an access token, it may use the token to access the user&#8217;s account via the API, limited to the scope of access, until the token expires or is revoked.<\/p>\n<p>Here is an example of an API request, using\u00a0<code>curl<\/code>. Note that it includes the access token:<\/p>\n<pre class=\"code-pre \"><code>curl -X POST -H \"Authorization: Bearer <span class=\"highlight\">ACCESS_TOKEN<\/span>\"\"https:\/\/api.digitalocean.com\/v2\/<span class=\"highlight\">$OBJECT<\/span>\" \r\n<\/code><\/pre>\n<p>Assuming the access token is valid, the API will process the request according to its API specifications. If the access token is expired or otherwise invalid, the API will return an &#8220;invalid_request&#8221; error.<\/p>\n<div data-unique=\"refresh-token-flow\"><\/div>\n<h2 id=\"refresh-token-flow\">Refresh Token Flow<\/h2>\n<p>After an access token expires, using it to make a request from the API will result in an &#8220;Invalid Token Error&#8221;. At this point, if a refresh token was included when the original access token was issued, it can be used to request a fresh access token from the authorization server.<\/p>\n<p>Here is an example POST request, using a refresh token to obtain a new access token:<\/p>\n<pre class=\"code-pre \"><code>https:\/\/cloud.digitalocean.com\/v1\/oauth\/token?grant_type=refresh_token&amp;client_id=<span class=\"highlight\">CLIENT_ID<\/span>&amp;client_secret=<span class=\"highlight\">CLIENT_SECRET<\/span>&amp;refresh_token=<span class=\"highlight\">REFRESH_TOKEN<\/span>\r\n<\/code><\/pre>\n<div data-unique=\"conclusion\">\u00a0source:\u00a0https:\/\/www.digitalocean.com\/community\/tutorials\/an-introduction-to-oauth-2<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Introduction OAuth 2 is an authorization framework that enables applications to obtain limited access to user accounts on an HTTP service, such as Facebook, GitHub, and DigitalOcean. It works by delegating user authentication to the service that hosts the user account, and authorizing third-party applications to access the user account. OAuth 2 provides authorization flows\u2026 <span class=\"read-more\"><a href=\"https:\/\/adriangrigoras.com\/blog\/introduction-oauth-2\/\">Read More &raquo;<\/a><\/span><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[30],"tags":[],"class_list":["post-839","post","type-post","status-publish","format-standard","hentry","category-architecture"],"_links":{"self":[{"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/posts\/839","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/comments?post=839"}],"version-history":[{"count":1,"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/posts\/839\/revisions"}],"predecessor-version":[{"id":840,"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/posts\/839\/revisions\/840"}],"wp:attachment":[{"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/media?parent=839"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/categories?post=839"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/adriangrigoras.com\/blog\/wp-json\/wp\/v2\/tags?post=839"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}