Prompt
How do I build a login flow with redirect URIs and consent screens?
Latest observation
A solid login flow with redirect URIs and consent screens is usually built around OAuth 2.0 / OpenID Connect (OIDC). The safest and most common pattern for web/mobile apps is the Authorization Code flow with PKCE.
1) Core pieces
You typically have:
- Client app: your website, mobile app, or SPA
- Authorization server / Identity provider (IdP): handles login, consent, token issuance
- Resource server / API: the backend API the app wants to call
- Redirect URI: where the IdP sends the user back after login/consent
2) Recommended flow: Authorization Code + PKCE
High-level steps
- User clicks Log in
- Your app redirects the browser to the IdP’s
/authorizeendpoint - User authenticates with the IdP
- IdP shows a consent screen if needed
- IdP redirects back to your redirect URI with an authorization
code - Your app exchanges that
codefor tokens at the IdP’s token endpoint - Your app uses the access token to call APIs; if using OIDC, it also uses the ID token for user identity
3) Redirect URI setup
A redirect URI must be:
- Pre-registered with the IdP
- Exact match (scheme, host, path, and often query rules depending on provider)
- Ideally a route dedicated to handling the callback, e.g.:
https://app.example.com/auth/callbackmyapp://auth/callbackfor mobile apps
Why exact matching matters
This prevents attackers from intercepting authorization codes by sending users to malicious callback URLs.
4) Authorization request example
Your app sends the browser to something like:
GET /authorize?
response_type=code&
client_id=abc123&
redirect_uri=https%3A%2F%2Fapp.example.com%2Fauth%2Fcallback&
scope=openid%20profile%20email&
state=randomState123&
code_challenge=...&
code_challenge_method=S256
Important parameters
response_type=code: use authorization code flowclient_id: your app’s public identifierredirect_uri: where the user returnsscope: requested permissionsstate: CSRF protection and request correlationcode_challenge/code_challenge_method: PKCE protection
5) Consent screen behavior
The consent screen shows the user:
- Who is requesting access
- What data/scopes are being requested
- What app name/logo is being used
- Potentially what actions the app can perform
When consent is shown
Usually when:
- The app is requesting scopes the user hasn’t already approved
- The user is first connecting the app
- The IdP policy requires explicit consent
Best practices
- Request only the scopes you truly need
- Use human-readable scope names on the consent UI
- Clearly show the app name and domain
- Allow the user to deny consent without breaking account access
6) Callback handling
After login/consent, the IdP redirects to:
https://app.example.com/auth/callback?code=AUTH_CODE&state=randomState123
Your app should:
- Verify
statematches what it originally generated - Verify the callback came on an allowed redirect URI
- Exchange
codefor tokens using the token endpoint - Store tokens securely
- Establish your app session
7) Token exchange example
Your backend sends:
POST /token
Content-Type: application/x-www-form-urlencoded
grant_type=authorization_code&
code=AUTH_CODE&
redirect_uri=https%3A%2F%2Fapp.example.com%2Fauth%2Fcallback&
client_id=abc123&
code_verifier=original_verifier
The IdP returns something like:
{
"access_token": "eyJ...",
"id_token": "eyJ...",
"refresh_token": "def...",
"expires_in": 3600,
"token_type": "Bearer"
}
8) Session handling
After successful token exchange, you have two common options:
Option A: Server-side session
- Create your own session cookie
- Keep OAuth tokens on the server
- Best for traditional web apps
Option B: Token-based frontend
- Frontend stores/accesses tokens
- Common in SPAs, but requires careful token handling
- Prefer BFF (Backend for Frontend) patterns when possible
Security tips
- Use HTTP-only, Secure, SameSite cookies for sessions
- Avoid storing tokens in
localStorageif you can - Use short-lived access tokens
- Rotate refresh tokens when supported
9) Logout flow
If using OIDC:
- Clear your app session
- Optionally redirect to the IdP’s logout endpoint
- Optionally pass a post-logout redirect URI (also pre-registered)
10) Security checklist
- Use Authorization Code + PKCE
- Validate
state - Validate
redirect_uri - Only allow exact, pre-registered callback URLs
- Use HTTPS everywhere
- Request minimal scopes
- Protect against open redirects
- Validate ID token signature, issuer, audience, expiration
- Rotate and protect refresh tokens
- Consider CSRF protection on session endpoints
- Log auth events, but never secrets
11) Simple sequence diagram
User -> App: Click Login
App -> IdP: Redirect to /authorize
IdP -> User: Login / Consent screen
IdP -> App: Redirect to redirect_uri?code=...
App -> IdP: Exchange code for tokens
IdP -> App: Tokens
App -> User: Logged in session
12) If you’re building your own auth system
If you’re implementing the auth server yourself, you’ll need:
- Client registration
- Redirect URI allowlisting
- Authorization code generation and storage
- PKCE verification
- Consent storage
- Token issuance and signing
- Session management
- Revocation and logout
- Audit logs
But unless you have a strong reason, it’s usually better to use an established IdP like:
- Auth0
- Okta
- Azure AD / Entra ID
- Google Identity Platform
- Keycloak
- Cognito
If you want, I can also give you:
- a working example in Node/Express, Python, or Next.js, or
- a database schema for storing clients, redirect URIs, grants, and consent records.