Integration Guide
A deep dive into how AuthGate's proxy flow works and how to integrate it into your application.
How the flow works
AuthGate acts as an OAuth proxy between your application and OAuth providers. Here's the complete flow:
- Your app redirects the user to AuthGate's proxy endpoint
- AuthGate validates the request (project exists, provider enabled, callback URL registered)
- AuthGate generates a PKCE code verifier and state, then redirects to the provider's authorization page
- The user authenticates with the provider (e.g., Google, GitHub)
- The provider redirects back to AuthGate's callback endpoint
- AuthGate exchanges the authorization code for tokens
- AuthGate extracts and normalizes user info from the provider
- AuthGate creates or updates the end user in its database
- AuthGate signs a JWT with the user's info and redirects to your callback URL
Initiating the login flow
Call the proxy endpoint from your server with the API key in the Authorization header:
POST /api/proxy/{provider}
Authorization: Bearer {AUTHGATE_API_KEY}
Content-Type: application/json
- Name
provider- Type
- string
- Description
The OAuth provider to use. One of:
google,github,discord,azure,apple.
- Name
callback_url- Type
- string
- Description
The URL to redirect to after authentication. Must be registered in your project's callback URLs.
- Name
state- Type
- string
- Description
Optional. An opaque value passed through to your callback URL. Useful for CSRF protection or storing redirect targets.
The project is resolved automatically from the API key. The response returns a redirect_url — redirect the user there to start the OAuth flow.
Handling the callback
After authentication, AuthGate redirects to your callback URL with tokens as query parameters:
{callback_url}?token={jwt_token}&refresh_token={refresh_token}&state={state}
The token is a short-lived JWT (5 minutes) signed with your project's secret. Always verify this token server-side using the Token Verification API — never trust it on the client.
// Server-side token verification
const res = await fetch(`${AUTHGATE_URL}/api/v1/token/verify`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ token }),
})
const { valid, user, expiresAt } = await res.json()
JWT payload
The JWT token contains the following claims:
- Name
sub- Type
- string
- Description
The AuthGate end user ID.
- Name
email- Type
- string | null
- Description
The user's email address from the provider.
- Name
name- Type
- string | null
- Description
The user's display name from the provider.
- Name
picture- Type
- string | null
- Description
URL to the user's avatar from the provider.
- Name
provider- Type
- string
- Description
The OAuth provider used (e.g.,
github,google).
Account linking
Account linking allows a single end user to authenticate through multiple OAuth providers. This must be explicitly enabled in your project settings (allowAccountLinking).
When enabled, there are two linking mechanisms:
Email-based linking — when a user authenticates with a new provider using an email that matches an existing end user, AuthGate links the new provider to the existing account. This only happens when allowAccountLinking is enabled; otherwise, a new end user is created.
Explicit linking — to link a new provider to a user who is already authenticated, pass link_to (the target user ID) and link_token (a valid JWT for that user, proving ownership) when initiating the OAuth flow:
{
"callback_url": "https://myapp.com/auth/callback",
"link_to": "user_abc123",
"link_token": "eyJhbGciOiJIUzI1NiIs..."
}
The link_token must be a valid JWT issued by AuthGate where the sub claim matches link_to. This prevents unauthorized users from linking providers to accounts they don't own.
Error handling
Errors can occur at two stages: during request validation (before the OAuth flow starts) and during the OAuth flow itself (after the user has been redirected to the provider).
If you're using the SDK (@auth-gate/nextjs or @auth-gate/react), most of these errors are caught automatically at startup. The SDK validates your API key and callback URL when your app starts and logs clear errors to the console. See the SDK docs for details.
Validation errors (JSON responses)
If the initial request to /api/proxy/{provider} fails validation, AuthGate returns a JSON error response with an appropriate HTTP status code:
// 401 Unauthorized
{ "error": "Invalid API key" }
// 400 Bad Request
{ "error": "Missing callback_url parameter" }
// 400 Bad Request
{ "error": "Unsupported provider" }
// 404 Not Found
{ "error": "Project not found or inactive" }
// 403 Forbidden
{ "error": "Callback URL not registered for this provider" }
// 403 Forbidden
{ "error": "Provider not enabled for this project" }
// 429 Too Many Requests
{ "error": "Too many requests" }
OAuth callback errors (JSON responses)
If authentication fails during the callback phase (e.g., the user denies access or the code exchange fails), AuthGate returns a JSON error from the callback endpoint rather than redirecting to your app:
// 400 Bad Request — user denied access or missing params
{ "error": "Missing code or state" }
// 400 Bad Request — state was already consumed or invalid
{ "error": "Invalid state" }
// 400 Bad Request — state expired (10 minute TTL)
{ "error": "State expired" }
// 500 Internal Server Error — code exchange with provider failed
{ "error": "Token exchange failed" }