OAuth 2.0 - Before You Start: Pick the Right Flow for Your Website, SPA, Mobile App, TV App, and CLI

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

We learned how OAuth 2.0 works in general in What on Earth is OAuth? and learned how to securely store access tokens in the front end. 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).

  • 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:

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

→ 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

  • 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:

  • 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

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, and set the redirect URL to be

  • On step 5, the user's browser will redirect to
  • 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

  • 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.

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

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

  • 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

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

  • 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

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 – 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:


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

Questions & Feedback

If you need help or have any feedback, ping us on Cotter's Slack Channel! 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 and check out our documentation.

Made in Typedream