OAuth 2.0 - Before You Start: Pick the Right Flow for Your Website, SPA, Mobile App, TV App, and CLI
Tags: javascript, security, webdev, react
Published: 2020-08-04 17:03:17

---
title: OAuth 2.0 - Before You Start: Pick the Right Flow for Your Website, SPA, Mobile App, TV App, and CLI
published: true
date: 2020-08-04 10:55:23 UTC
tags: javascript, security, webdev, react
canonical_url: https://blog.cotter.app/oauth-20-before-you-start-pick-the-right-flow-for-your-website-spa-mobile-app-tv-app-and-clis/
series: OAuth 2.0, JWT Tokens, and How to Store Them Securely
---

*OAuth 2.0 has at least 4 different flows for different use cases. Find out which flow you should use to secure your app.*

 ![OAuth 2.0 - Before You Start: Pick the Right Flow for Your Website, SPA, Mobile App, TV App, and CLI](https://blog.cotter.app/content/images/2020/08/Cover.png)

We learned how OAuth 2.0 works in general in [What on Earth is OAuth?](https://dev.to/cotter/what-on-earth-is-oauth-a-super-simple-intro-to-oauth-2-0-access-tokens-and-how-to-implement-it-in-your-site-48jo) and learned [how to securely store access tokens in the front end.](https://dev.to/cotter/localstorage-vs-cookies-all-you-need-to-know-about-storing-jwt-tokens-securely-in-the-front-end-15id) In this post, we'll learn which OAuth 2.0 flow you should use based on what you're building.

# OAuth 2.0 Recap:

In general, the OAuth 2.0 flow looks like this diagram below (if you're not familiar with the OAuth 2.0 Flow below, [check our explanation here](https://dev.to/cotter/what-on-earth-is-oauth-a-super-simple-intro-to-oauth-2-0-access-tokens-and-how-to-implement-it-in-your-site-48jo)).

![OAuth 2.0 - Before You Start: Pick the Right Flow for Your Website, SPA, Mobile App, TV App, and CLI](https://blog.cotter.app/content/images/2020/07/image-5.png)<figcaption>OAuth 2.0 Flow with Google Sign In</figcaption>

- **Step 1:** The website requests authorization for Albert. Albert is being redirected to Google's site to log in.
- **Step 2:** Google's site returned with an **Authorization Grant.**  **This is the part that has several different cases based on which flow you're using.**
- **Step 3-4:** Depending on the flow, the client will have a way to exchange this **Authorization Grant** with an access token, and sometimes a refresh token
- **Step 5-6:** The website uses the access token to access resources.

# Common OAuth 2.0 Flows

As mentioned above, there are 4 common OAuth 2.0 Flows:

- [Authorization Code Flow](#authorization-code-flow)
- [Authorization Code Flow with Proof Key for Code Exchange (PKCE)](#authorization-code-flow-with-pkce)
- [Client Credentials Flow](#client-credentials-flow)
- [Device Code Flow](#device-code-flow)

# Which Flow Should I Use?

Different apps should use different flows based on whether or not the app can hold secrets securely.

- **[Web Server Apps and Command Line Scripts](#web-server-apps-and-command-line-scripts):** Use Authorization Code Flow
- **[Single Page Apps and Mobile Apps](#single-page-apps-amp-mobile-apps):** Use Authorization Code Flow with PKCE
- [**Server-to-Server API Calls** :](#servertoserver-api-calls) Use Client Credentials Flow
- **[TV Apps and other apps on input-constrained devices](#tv-apps-and-other-apps-on-inputconstrained-devices)**: Use Device Code Flow

## Web Server Apps and Command Line Scripts

### → Use Authorization Code Flow

Web Server Apps are apps that are running on a server where the source code is not publicly exposed.

**Requirements:** Your app needs to be able to hold a Client Secret securely in the back end server.

For example:

- ✅ Your app runs on a server (Node.js, PHP, Java, .NET): Your server code is not publicly exposed and you can put secret keys in environment variables without it being visible to users of the application.
- ❌ React-only website: React is a SPA framework, your code is publicly exposed, and therefore cannot hold secrets securely, even if you put secrets in .env files.

### Authorization Code Flow

![OAuth 2.0 - Before You Start: Pick the Right Flow for Your Website, SPA, Mobile App, TV App, and CLI](https://blog.cotter.app/content/images/2020/08/image-1.png)<figcaption>OAuth 2.0 Authorization Code Flow</figcaption>

- **Step 1-4:** User clicks Sign in with Google, and get redirected to Google's Site to authenticate. 
- **Step 5:** When the user successfully authenticated, Google will redirect the user back to your website, and include an `authorization_code` in the redirect URL. For example:

```
https://mysite.com/redirect
    ?code=ABCDEFGHIJ12345
    &state=abcde123abc
```

- **Step 6-9:**  With the code above and a Client ID + Client Secret that you get from Google when registering an application, you can request for an `access_token` for the user that you can then use to fetch data.

See the full spec at [RFC 6749 Section 4.1](https://tools.ietf.org/html/rfc6749#section-4.1)

### How do I do this from the command line?

- On **step 3** , show the URL that the user should go to in their browser.
- Get your script to listen to a local port, for example, `http://127.0.0.1:8000` and set the redirect URL to be `http://127.0.0.1:8000/redirect` 
- On **step 5** , the user's browser will redirect to

```
https://127.0.0.1:8000/redirect
    ?code=ABCDEFGHIJ12345
    &state=abcde123abc
```

- Your script should then handle this `GET` request, parse the `code` and `state` and proceed to step 6-9.

## Single Page Apps & Mobile Apps

### → Use Authorization Code Flow with PKCE

Single Page Apps (SPA) and Mobile Apps are not able to hold secrets securely because their source code is publicly exposed or can be decompiled.

### How does the PKCE flow work without a Client Secret?

The PKCE flow requires the app to generate a secret on the fly. This secret is generated **at the beginning of the flow** when the user started the login flow and then **checked when exchanging authorization code with an access token.**

This makes sure that the entity that is requesting to exchange the authorization code with an access token is still the same entity where the user requested to authenticate.

### Authorization Code Flow with PKCE

![OAuth 2.0 - Before You Start: Pick the Right Flow for Your Website, SPA, Mobile App, TV App, and CLI](https://blog.cotter.app/content/images/2020/08/image-2.png)<figcaption>OAuth 2.0 Authorization Code Flow with PKCE</figcaption>

- **Step 1:** User clicks the login button in your app
- **Step 2:** Generate a `code_verifier` and `code_challenge`, then make an authorization request by sending the `code_challenge`.

```
code_verifier = "a cryptographic random string"
code_challenge = base64url_encode(sha256(ascii(code_verifier)))
```

- **Step 3-5:** The Authorization Server will save the `code_challenge` for later and redirect the user to log in, then redirect to your app with an `authorization_code`
- **Step 6** : Your app then sends the `code_verifier` , `client_id` , and `authorization_code` to get an access token.
- **Step 7:** The Authorization Server will check if the original `code_challenge == base64url_encode(sha256(ascii(code_verifier)))`. This is where it determines whether the entity that started this flow is the same one as the one that is currently requesting an access token. If yes, it returns the access token.
- **Step 8-9** : Your app can now fetch data using the access token.

See the full spec at [RFC 7636](https://tools.ietf.org/html/rfc7636).

Here are some resources to help you generate a code challenge and verifier:

- [Generate `code_verifier` and `code_challenge` online](https://example-app.com/pkce).
- See how to [generate `code_verifier` and `code_challenge` using JavaScript, Java, or Swift 3](https://docs.cotter.app/sdk-reference/api-for-other-mobile-apps/api-for-mobile-apps).

## Server-to-Server API calls

### → Use Client Credentials Flow

For example, your back end server wants to call an API endpoint at Stripe to retrieve a list of payments. This is a **machine-to-machine authorization, and there's no end-user authorization.** In this case, Stripe is only trying to authorize your server to access the API endpoint. Since your server can also hold secrets securely, all you need for accessing the data is a **Client ID and Client Secret**.

### Client Credentials Flow

![OAuth 2.0 - Before You Start: Pick the Right Flow for Your Website, SPA, Mobile App, TV App, and CLI](https://blog.cotter.app/content/images/2020/08/image-3.png)<figcaption>OAuth 2.0 Client Credentials Flow</figcaption>

- **Step 1:** Your server authenticates itself using its Client ID and Client Secret. Notice that this doesn't involve any user. This is because your server is acting as itself. (For example, your server is acting as **Hello Merchant** that you registered to Stripe).
- **Step 2:** If the Client ID and Client Secret checks out, you'll receive an access token.
- **Step 3:** Use the access token to fetch data. 

See the full spec at [RFC 6749 Section 4.4](https://tools.ietf.org/html/rfc6749#section-4.4)

## TV Apps and other apps on input-constrained devices

### → Use Device Code Flow

It'll be horrible if you have to input your super-secure Google password to watch YouTube on your brand new smart TV, right? OAuth 2.0 Device Code Flow is designed so that you can authorize apps on an input constraint device **by opening a URL and entering a code on your browser (on your phone/laptop).**

**Requirements:** Your app needs to be able to display a URL and a User Code to the user. This can also be done by showing a QR Code.

### Device Code Flow

![OAuth 2.0 - Before You Start: Pick the Right Flow for Your Website, SPA, Mobile App, TV App, and CLI](https://blog.cotter.app/content/images/2020/08/image-5.png)

- **Step 1:** User requests to log in on your TV App.
- **Step 2-3:** Your TV App makes an authorization request to the Authorization Server (Google Accounts in this case) with your app's Client ID, and receive 3 things: a `device_code`, a `user_code` , and a `verification_uri`.
- **Step 4** : Your TV App now asks the user to go to the `verification_uri` and enter the `user_code` . You can optionally do this by asking the user to scan a QR Code that encodes both the `verification_uri` and the `user_code` .
- **Step 5:** Your TV App now requests an access token to the Authorization Server using the `device_code` and `client_id` . If the user hasn't authenticated and allowed access to your app yet (they haven't gone to the `verification_uri`), the Authorization Server will respond with an error `authorization_pending`. Your TV App should keep on requesting until you get an access token.
- **Step 6:** The user typed in the `verification_uri` on their phone or laptop, and entered the `user_code`. 
- **Step 7-8:** The user is now redirected to Google's Login page where they can authenticate and allow your TV App to access certain data.
- **Step 9** : Google accounts now mark that your user has authenticated and allowed your app to access their data. The next time your app requested for an access token with the `device_code`, Google Accounts will return an access token.
- **Step 10-11** : Use the access token to fetch data.

See the full spec at [RFC 8628 Section 3.4](https://tools.ietf.org/html/rfc8628#section-3.4)

## That's It!

This should help you pick which OAuth 2.0 flow you need for different use cases. We didn't go into the specific HTTP Request parameters that you should use, we will cover that next time.

This post is written by the team at [Cotter](https://www.cotter.app/) – we are building lightweight, fast, and passwordless login solution for websites and mobile apps. If you're building a website, we have a ready-made solution that implements the flows above for you.

**Sign in with Magic Link via Email, SMS, or WhatsApp on:**

- [React.js](https://docs.cotter.app/quickstart-guides/react-magic-link-with-email-and-phone)
- [React Native](https://docs.cotter.app/sdk-reference/react-native/react-native-sdk-verify-email-phone)
- [Flutter](https://docs.cotter.app/sdk-reference/flutter/sign-in-with-email-phone-number)

* * *

## References

We referred to these articles and specs to write this post:

- [The OAuth 2.0 Authorization Framewor](https://tools.ietf.org/html/rfc6749#section-4)k (RFC 6749)
- [OAuth Grant Types](https://oauth.net/2/grant-types/)
- [OAuth 2.0 Device Flow Grant](https://alexbilbie.com/2016/04/oauth-2-device-flow-grant/)
- [Authentication and Authorization Flows](https://auth0.com/docs/flows)

* * *

### Questions & Feedback

If you need help or have any feedback, ping us on [Cotter's Slack Channel](https://join.slack.com/t/askcotter/shared_invite/zt-dxzf311g-5Mp3~odZNB2DwYaxIJ1dJA)! We're here to help.

### Ready to use Cotter?

If you enjoyed this post and want to integrate Cotter into your website or app, you can [create a free account](https://dev.cotter.app/) and [check out our documentation](https://docs.cotter.app/).