Better Auth in Rust

OAuth

Understanding the OAuth 2.0 authorization flow in Better Auth.

Better Auth implements the OAuth 2.0 Authorization Code flow with PKCE for secure social sign-in. This page explains the concepts behind the OAuth integration.

OAuth 2.0 Flow

The authorization code flow with PKCE works as follows:

Key Concepts

Authorization Code

The authorization code is a short-lived, single-use code returned by the OAuth provider after user authorization. Better Auth exchanges this code for access and refresh tokens.

PKCE (Proof Key for Code Exchange)

Better Auth uses PKCE for all OAuth flows, which protects against authorization code interception attacks:

  1. Code Verifier: A cryptographically random string generated for each authorization request
  2. Code Challenge: The SHA-256 hash of the verifier, sent in the authorization URL
  3. Verification: During token exchange, the original verifier is sent to prove the request comes from the same client

This is especially important for mobile and SPA applications where the client secret cannot be kept confidential.

State Parameter

A random UUID is generated for each OAuth request and stored as a verification record. This prevents CSRF attacks by ensuring the callback matches a legitimate authorization request.

Providers

An OAuth provider configuration includes:

FieldDescription
client_idYour application's ID from the provider
client_secretYour application's secret from the provider
auth_urlThe provider's authorization endpoint
token_urlThe provider's token exchange endpoint
user_info_urlThe provider's user info API endpoint
scopesDefault scopes to request
map_user_infoFunction to transform provider-specific JSON into OAuthUserInfo

Tokens

After a successful OAuth flow, Better Auth stores:

TokenDescription
access_tokenUsed to call the provider's APIs on behalf of the user
refresh_tokenUsed to obtain a new access token when it expires
id_tokenOpenID Connect identity token (if the provider supports it)

These tokens are stored in the account table and can be retrieved via the /get-access-token endpoint.

Account Linking

Better Auth handles several scenarios during the OAuth callback:

New User

If no user exists with the email from the provider, a new user and account are created.

Existing Email

If a user with the same email already exists (from a different provider or email/password), the new provider is automatically linked to the existing user.

Existing Provider Account

If the user has previously signed in with this provider, the stored tokens are updated and a new session is created.

Explicit Linking

Authenticated users can explicitly link additional providers via the /link-social endpoint. This starts a new OAuth flow that, on completion, creates an account record linking the provider to the existing user.

Security Considerations

  • PKCE is mandatory: All OAuth flows use PKCE with S256 code challenge method
  • State validation: Every callback validates the state parameter against stored verification records
  • Short-lived state: OAuth state verification records expire after 10 minutes
  • Token storage: Access and refresh tokens are stored server-side in the database, never exposed to the client
  • Automatic cleanup: Verification records are deleted after successful use

See Also

On this page