Skip to the content.

Explore OAuth

What is OAuth

OAuth is a industry-standard protocol for authorization. It is for authorization, instead of authentication.

Terminologies

How OAuth works

Authorization code flow

authorization-code-flow

Authorization code flow Request to get auth token

GET {Authorization Endpoint}
  ?response_type=code             // - Required
  &client_id={Client ID}          // - Required
  &redirect_uri={Redirect URI}    // - Conditionally required
  &scope={Scopes}                 // - Optional
  &state={Arbitrary String}       // - Recommended
  &code_challenge={Challenge}     // - Optional
  &code_challenge_method={Method} // - Optional
  HTTP/1.1
HOST: {Authorization Server}

Authorization code flow Response with auth token

HTTP/1.1 302 Found
Location: {Redirect URI}
  ?code={Authorization Code}  // - Always included
  &state={Arbitrary String}   // - Included if the authorization
                              //   request included 'state'.

Authorization code flow Request to get access token using auth token

POST {Token Endpoint} HTTP/1.1
Host: {Authorization Server}
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code  // - Required
&code={Authorization Code}     // - Required
&redirect_uri={Redirect URI}   // - Required if the authorization
                               //   request included 'redirect_uri'.
&code_verifier={Verifier}      // - Required if the authorization
                               //   request included
                               //   'code_challenge'.

Authorization code flow Response with access token

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
  "access_token": "{Access Token}",    // - Always included
  "token_type": "{Token Type}",        // - Always included
  "expires_in": {Lifetime In Seconds}, // - Optional
  "refresh_token": "{Refresh Token}",  // - Optional
  "scope": "{Scopes}"                  // - Mandatory if the granted
                                       //   scopes differ from the
                                       //   requested ones.
}

Implicit flow

implicit-flow

Implicit flow Request to get access token

GET {Authorization Endpoint}
  ?response_type=token          // - Required
  &client_id={Client ID}        // - Required
  &redirect_uri={Redirect URI}  // - Conditionally required
  &scope={Scopes}               // - Optional
  &state={Arbitrary String}     // - Recommended
  HTTP/1.1
HOST: {Authorization Server}

Implicit flow Response with access token

HTTP/1.1 302 Found
Location: {Redirect URI}
  #access_token={Access Token}       // - Always included
  &token_type={Token Type}           // - Always included
  &expires_in={Lifetime In Seconds}  // - Optional
  &state={Arbitrary String}          // - Included if the request
                                     //   included 'state'.
  &scope={Scopes}                    // - Mandatory if the granted
                                     //   scopes differ from the
                                     //   requested ones.

Resource owner password credentials flow

resource-owner-password-credentials-flow

Resource owner password credentials flow Request to get access token

POST {Token Endpoint} HTTP/1.1
Host: {Authorization Server}
Content-Type: application/x-www-form-urlecoded
grant_type=password    // - Required
&username={User ID}    // - Required
&password={Password}   // - Required
&scope={Scopes}        // - Optional

Resource owner password credentials flow Response with access token

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
  "access_token": "{Access Token}",    // - Always included
  "token_type": "{Token Type}",        // - Always included
  "expires_in": {Lifetime In Seconds}, // - Optional
  "refresh_token": "{Refresh Token}",  // - Optional
  "scope": "{Scopes}"                  // - Mandatory if the granted
                                       //   scopes differ from the
                                       //   requested ones.
}

Client credentials flow

client-credentials-flow

Client credentials flow Request to get access token

POST {Token Endpoint} HTTP/1.1
Host: {Authorization Server}
Authorization: Basic {Client Credentials}
Content-Type: application/x-www-form-urlecoded
grant_type=client_credentials  // - Required
&scope={Scopes}                // - Optional

Client credentials flow Response with access token

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
  "access_token": "{Access Token}",    // - Always included
  "token_type": "{Token Type}",        // - Always included
  "expires_in": {Lifetime In Seconds}, // - Optional
  "scope": "{Scopes}"                  // - Mandatory if the granted
                                       //   scopes differ from the
                                       //   requested ones.
}

Refresh token flow

refresh-token-flow

Refresh token flow Request to get the new access token

POST {Token Endpoint} HTTP/1.1
Host: {Authorization Server}
Content-Type: application/x-www-form-urlecoded
grant_type=refresh_token        // - Required
&refresh_token={Refresh Token}  // - Required
&scope={Scopes}                 // - Optional

Refresh token flow Response with new access token

HTTP/1.1 200 OK
Content-Type: application/json;charset=UTF-8
Cache-Control: no-store
Pragma: no-cache
{
  "access_token": "{Access Token}",    // - Always included
  "token_type": "{Token Type}",        // - Always included
  "expires_in": {Lifetime In Seconds}, // - Optional
  "refresh_token": "{Refresh Token}",  // - Optional
  "scope": "{Scopes}"                  // - Mandatory if the granted
                                       //   scopes differ from the
                                       //   original ones.
}

Which flow you should choose

And this link describes how Authorization flow with PKCE works.

What is PKCE

It is possible that a malicious process from the client side intercept the authorization token and use that token to ask for the access token. So that we need to have a mechanism to protect it. We call it PKCE(proof key for code exchange).

auth-code-interception-attach

Below are the steps of PKCE

pkce-request-auth-code

pkce-return-auth-code

pkce-request-access-code

pkce-return-access-code

How login via Google, Github, Twitter, FB works in a third party app

There are a lot of web app uses this feature, like medium.com which allows user to login via Github. The idea is behind the scene is that medium.com wants to get the user profile, so it does the OAuth to the user profile provider. Since user will be redirected to the profile provider to login first, so from user point of view it is login via Github.

What flow should I use

what-flow-should-i-use

References