How toUse client_id and client_secret in OAuth2

When you register an OAuth2 application, you're issued two important credentials: a client_id and, for confidential clients, a client_secret.

These two values act like the username and password of your app when it communicates with the Authorization Server.

Public vs. Confidential Clients

OAuth2 defines two types of clients:

  • Public clients: apps that can't securely store secrets, like mobile apps and SPAs.
  • Confidential clients: apps that can keep secrets safe, like server-rendered web apps or backend services.

If you're building a web app using React Router, you're likely in the confidential client category—so you’ll use both client_id and client_secret in your token requests.

Authenticating Your App

When exchanging an authorization code for an access token, your app must authenticate itself to the Authorization Server.

You do this by sending the client_id and client_secret using HTTP Basic Auth:

let response = await fetch("https://auth.example.com/token", {
  method: "POST",
  headers: {
    "Content-Type": "application/x-www-form-urlencoded",
    Authorization:
      "Basic " +
      btoa(`${process.env.CLIENT_ID}:${process.env.CLIENT_SECRET}`),
  },
  body: new URLSearchParams({
    grant_type: "authorization_code",
    code: codeFromCallback,
    redirect_uri: "https://example.com/callback",
  }),
});

let tokens = await response.json();

This is how the Authorization Server confirms that the request is coming from a valid, registered app.

What About Public Clients?

Since public clients (like SPAs and mobile apps) can't safely store secrets, they use PKCE instead of client_secret. It's a secure alternative designed specifically for these types of clients.

If you’re not familiar with PKCE, I wrote a guide explaining how it works.


Want to build secure OAuth2 flows in React Router or Remix apps? I'm writing a book about it.

It will cover everything from the basics of OAuth2 to advanced topics like PKCE, refresh tokens, and more Check it out at books.sergiodxa.com