The authorization code flow is the usual pattern when the browser leaves your site, the user signs in at Intastellar, and Intastellar sends them back to your site with a one-time code you swap for tokens.
This article vs the React / plain JS popup flow
If you use @intastellar/signin-sdk-react or the plain HTML/JS bundle, sign-in usually runs in a popup and a token arrives via postMessage. You do not manually build the GET authorize URL and POST token request in that mode.
Use this page when your team implements authorize + callback + token (custom stack, some mobile setups, or server-driven web apps). For choosing client types first, see Getting started.
Parameter names below follow common OAuth 2.0 / OIDC usage — confirm exact names, scopes, and discovery URLs in your Intastellar registration and technical reference.
What you need
- Registered client ID, redirect URI, and (for confidential clients) client secret.
- A safe place to store
stateand the PKCEcode_verifierbetween redirect steps. - HTTPS redirect URIs in production.
Step 1 — Send the user to authorize
Send the browser to the authorization endpoint with query parameters:
| Parameter | Purpose |
|---|---|
response_type | Use code for this flow. |
client_id | Your registered client ID. |
redirect_uri | Must exactly match a registered URI. |
scope | Space-separated scopes (often includes openid for OIDC). |
state | Random, unguessable value; you verify it on return. |
code_challenge | PKCE: SHA-256 hash of code_verifier, Base64url-encoded (public clients). |
code_challenge_method | Typically S256. |
Example (line breaks for readability):
GET AUTHORIZATION_ENDPOINT?
response_type=code
&client_id=YOUR_CLIENT_ID
&redirect_uri=https%3A%2F%2Fapp.example.com%2Fauth%2Fcallback
&scope=openid%20profile%20email
&state=RANDOM_STATE
&code_challenge=CODE_CHALLENGE
&code_challenge_method=S256Store state and the raw code_verifier (for PKCE) server-side or in a secure, short-lived cookie so you can validate them on callback.
Step 2 — Handle the callback
Intastellar redirects to your redirect_uri with:
| Query param | Meaning |
|---|---|
code | One-time authorization code. |
state | Echo of the value you sent; must match stored state. |
If the user denies access or an error occurs, you may receive error and error_description instead — handle these without treating them as success.
Step 3 — Exchange the code for tokens
POST to the token endpoint (typically application/x-www-form-urlencoded):
| Field | Purpose |
|---|---|
grant_type | authorization_code |
code | The code from the callback. |
redirect_uri | Same URI as in step 1. |
client_id | Your client ID. |
code_verifier | PKCE: the original secret verifier (public clients). |
client_secret | Confidential clients only. |
The response usually includes access_token, optional refresh_token, and an id_token when openid was requested. Validate the ID token (issuer, audience, expiry, signature) using JWKS from the issuer when you rely on claims in your app.
Security checklist
- Never skip
stateverification — prevents CSRF on the callback. - Use PKCE for any client that cannot hold a client secret (SPAs, mobile).
- Use HTTPS for every redirect URI in production.
- Keep refresh tokens and client secrets only on servers you control.
Frequently asked questions
invalid_grant right after callback
Often code already used, expired code, or redirect_uri / PKCE mismatch. Codes are usually single-use. See Logout, errors, and troubleshooting.
Do we need PKCE on a server-only app?
If the browser starts the flow and there is no secret in the browser, yes. If a confidential server starts and finishes everything without exposing the secret, follow what your registration allows — still use state.
Next
- Redirect URIs and callbacks — tighten registration and avoid mismatch errors.
- Sessions, cookies, and tokens — after tokens arrive.
Last updated