Blog · Guides

OAuth grant types: which flow belongs in which application

Authorization code with PKCE, client credentials, device code and refresh tokens explained, with the deprecated flows to avoid and a table matching each grant to a client type.

Casdoor Team · November 1, 2026 · 3 min read

This guide is written by the team that builds Casdoor and describes the standards as published (listed under Sources), with notes on how Casdoor implements them as of November 1, 2026. Spotted a mistake? Tell us.

A grant type is the method a client uses to obtain an OAuth token. The grant is declared in the token request as grant_type, and picking the wrong one is the most common way OAuth integrations end up insecure.

This article covers the grants that matter, the ones to avoid, and which belongs in which kind of application.

Authorization code (with PKCE)

The default for anything involving a user: web apps, mobile apps, single-page apps, desktop apps.

  1. The client redirects the user to the authorization endpoint.
  2. The user approves.
  3. The provider redirects back with a short-lived code.
  4. The client exchanges the code for tokens at the token endpoint.

PKCE (RFC 7636) adds a per-request verifier so that a stolen code cannot be redeemed by someone else. It is required for public clients and recommended for confidential ones.

Use when: a human is signing in.

Client credentials

No user. The client authenticates with its own ID and secret, and gets a token for its own resources.

  1. The service posts its client credentials to the token endpoint.
  2. The provider returns an access token with the scopes the client is allowed.

Use when: service-to-service calls, cron jobs, backend integrations. The token represents the application, not a person — never use it to act as a user.

Device code

For devices that cannot run a browser or receive a redirect: TVs, CLIs over SSH, IoT.

  1. The device asks for a device code and a short user code.
  2. The device shows the user code and a verification URL.
  3. The user approves on a phone or laptop.
  4. The device polls the token endpoint until approved.

Use when: the client has no browser. See OAuth device flow.

Refresh token

Not a way to start a flow — a way to continue one. The client exchanges a refresh token for a new access token without user interaction.

  • Keep refresh tokens long-lived and access tokens short-lived.
  • Rotate refresh tokens on use where the provider supports it.
  • A refresh token is as sensitive as a password; store it accordingly.
  • The grant is refresh_token.

Deprecated grants to avoid

Implicit returns tokens directly in the URL fragment. Tokens end up in browser history, logs and referrers. The OAuth 2.1 draft removes it; use authorization code with PKCE.

Resource owner password credentials (ROPC) has the client collect the username and password directly. It defeats the purpose of OAuth, breaks MFA, and is removed in OAuth 2.1. Migrate to a browser flow.

Token exchange (advanced)

RFC 8693 defines urn:ietf:params:oauth:grant-type:token-exchange: trade one token for another, for cases like impersonation, delegation, or crossing trust domains. Most applications never need it, but it is the right tool for gateways and multi-service architectures.

Which grant for which client

Client Grant
Server-rendered web app Authorization code (confidential client)
Single-page app Authorization code + PKCE
Mobile / desktop app Authorization code + PKCE
CLI over SSH, TV, IoT Device code
Backend service Client credentials
Long-running app Refresh token (after a user flow)
Gateway / multi-service Token exchange, if needed

Common mistakes

  • Using client credentials to act as a user. The token has no user context; anything user-specific breaks or leaks across users.
  • Skipping PKCE in a public client. The authorization code becomes a bearer credential.
  • Long-lived access tokens. Revocation stops meaning anything. Prefer short access tokens plus refresh.
  • Requesting every scope up front. Ask for what the feature needs; additional access should be a separate consent.
  • Treating the access token as an identity token. It is not; use OpenID Connect for identity.

Related reading: what OAuth 2.0 is, OAuth vs OIDC and authorization for AI agents.