Authorization Flow
Step-by-step guide to the OAuth 2.0 Authorization Code flow.
OAuth 2.0 Authorization Code Flow
Cengel ID uses the standard OAuth 2.0 Authorization Code flow, which is the most secure method for server-side applications. The flow follows these steps:
Redirect User to Authorization Endpoint
Redirect the user's browser to the authorization endpoint with the required parameters:
GET /api/v2/oauth/authorize?
response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=YOUR_REDIRECT_URI
&scope=openid profile email
&state=RANDOM_STATE_STRING
&nonce=RANDOM_NONCE_STRING
Cengel ID prompts the user to log in (if not already authenticated) and grant permissions to your application.
User Grants Permission
After the user logs in (if not already authenticated) and grants permission on the consent screen, Cengel ID redirects them back to your redirect URI with an authorization code:
YOUR_REDIRECT_URI?
code=AUTHORIZATION_CODE
&state=RANDOM_STATE_STRING
If the user denies access, Cengel ID returns an error response instead:
YOUR_REDIRECT_URI?
error=access_denied
&error_description=User%20denied%20the%20request
&state=RANDOM_STATE_STRING
Exchange Code for Tokens
Exchange the authorization code for access, refresh, and ID tokens immediately. Perform this exchange server-side to protect your client secret:
POST /api/v2/oauth/token
Content-Type: application/json
{
"grant_type": "authorization_code",
"code": "AUTHORIZATION_CODE",
"client_id": "YOUR_CLIENT_ID",
"client_secret": "YOUR_CLIENT_SECRET",
"redirect_uri": "YOUR_REDIRECT_URI"
}
Important:Theredirect_uriin this request mustexactly matchthe one you used in Step 1, including protocol, domain, path, and query parameters (if any).
Successful response (200 OK):
{
"access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 1800,
"refresh_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"id_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}
Response Fields
| Field | Type | Status | Description |
|---|---|---|---|
| access_token | string | Required | JWT token for API access (expires in 30 minutes) |
| token_type | string | Required | Always "Bearer" |
| expires_in | number | Required | Access token lifetime in seconds (1800=30 minutes) |
| refresh_token | string | Required | JWT token for obtaining new access tokens (expires in 7 days) |
| id_token | string | Required | JWT containing user identity information (OpenID Connect) |
Use Access Token
Use the access token to make authenticated requests to the UserInfo endpoint or your own protected resources. Include it in the Authorization header:
GET /api/v2/oauth/userinfo
Authorization: Bearer YOUR_ACCESS_TOKEN
The access token contains the user's ID, email, client ID, and granted scopes. It's a JWT that you can decode (but not verify without the secret) to inspect its contents. Validate token expiration before making requests.
State Parameter
Thestateparameter is crucial for security. Generate a cryptographically random, unguessable string and store it (e.g., in a session or secure cookie). When Cengel ID redirects the user back, verify that the state parameter matches the one you sent.
This prevents CSRF attacks by ensuring that the authorization response came from the same request you initiated.
Nonce Parameter
Thenonceparameter prevents replay attacks in OpenID Connect. Generate a cryptographically random string and verify it in the ID token.
Cengel ID includes the nonce value in the ID token'snonceclaim. After receiving the ID token, decode it and verify that the nonce claim matches the one you sent in the authorization request.
Consent Management
When a user grants permission, Cengel ID creates a consent grant that persists the user's authorization for your application. We store this consent grant and use it to:
- Track which scopes the user granted to your application
- Allow users to revoke access through their account settings
- Automatically invalidate tokens when users revoke consent
- Enable seamless re-authorization for returning users
If a user revokes consent, we invalidate all existing tokens and the API returns 403 Forbidden. Handle this gracefully by prompting the user to re-authenticate.
