Introduction
In web applications, user authentication (verifying identity) and authorization (granting permissions) are the most critical security functions.
- Authentication: “Who are you?” → Verify user identity
- Authorization: “What can you do?” → Control access to resources
OAuth 2.0 is a framework for authorization, while OpenID Connect (OIDC) is an authentication layer built on top of OAuth 2.0. This article explains how each works and the security considerations to keep in mind.
OAuth 2.0 Overview
Four Roles
OAuth 2.0 defines four roles:
| Role | Description | Example |
|---|---|---|
| Resource Owner | Owner of the resource | End user |
| Client | Application accessing the resource | Web app, mobile app |
| Authorization Server | Server that issues tokens | Google, Auth0 |
| Resource Server | Provides protected resources | API server |
Client Registration
To use OAuth, you must register your client with the Authorization Server and obtain:
- client_id: Client identifier (public)
- client_secret: Client secret key (confidential, server-side only)
- redirect_uri: URL to redirect after authorization
OAuth 2.0 Grant Types
Authorization Code Grant
The most common flow for web applications.
1. Client → Authorization Server: Authorization request
GET /authorize?response_type=code
&client_id=CLIENT_ID
&redirect_uri=REDIRECT_URI
&scope=read write
&state=RANDOM_STATE
2. Resource Owner: Login & consent
3. Authorization Server → Client: Return authorization code
302 Redirect to REDIRECT_URI?code=AUTH_CODE&state=RANDOM_STATE
4. Client → Authorization Server: Token exchange (back channel)
POST /token
grant_type=authorization_code
&code=AUTH_CODE
&redirect_uri=REDIRECT_URI
&client_id=CLIENT_ID
&client_secret=CLIENT_SECRET
5. Authorization Server → Client: Return access token
{ "access_token": "...", "token_type": "bearer", "expires_in": 3600 }
Authorization Code + PKCE
SPAs and mobile apps cannot securely store client_secret, so PKCE (Proof Key for Code Exchange) is used.
- Client generates a random
code_verifier - Computes
code_challenge = BASE64URL(SHA256(code_verifier)) - Includes
code_challengein the authorization request - Sends
code_verifierduring token exchange - Authorization Server recomputes
code_challengefromcode_verifierto verify
This prevents token exchange even if the authorization code is intercepted.
Client Credentials Grant
Used for server-to-server (Machine-to-Machine) communication with no user involved.
POST /token
grant_type=client_credentials
&client_id=CLIENT_ID
&client_secret=CLIENT_SECRET
&scope=api:read
Deprecated Grant Types
- Implicit Grant: Token returned in URL fragment, high leakage risk. Deprecated in favor of PKCE.
- Resource Owner Password Credentials: User password passed directly to client, significant security concerns.
Access Tokens and Refresh Tokens
Access Tokens
Bearer tokens sent via the Authorization header in API requests.
GET /api/resource
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
- Expiration: Typically short-lived (15 minutes to 1 hour)
- Scope: Limits accessible resources
Refresh Tokens
Used to obtain new access tokens without re-authentication when the current token expires.
POST /token
grant_type=refresh_token
&refresh_token=REFRESH_TOKEN
&client_id=CLIENT_ID
OpenID Connect (OIDC)
What is OIDC?
OIDC is an authentication layer built on top of OAuth 2.0. While OAuth 2.0 handles “what can be accessed,” OIDC handles “who is the user.”
Adding scope=openid to the authorization request activates the OIDC flow.
ID Token (JWT)
OIDC issues an ID Token in addition to the access token. The ID Token is in JSON Web Token (JWT) format, consisting of three parts:
Header.Payload.Signature
Header:
{
"alg": "RS256",
"typ": "JWT",
"kid": "key-id-123"
}
Payload (Standard Claims):
| Claim | Description | Example |
|---|---|---|
sub | Unique user identifier | "user-123" |
iss | Token issuer | "https://auth.example.com" |
aud | Target client | "client-id" |
exp | Expiration (UNIX timestamp) | 1709942400 |
iat | Issued at | 1709938800 |
name | User name | "Taro Yamada" |
email | Email address | "taro@example.com" |
Signature: Signs Header + Payload with a secret key to detect tampering.
UserInfo Endpoint
Additional user information can be retrieved using the access token.
GET /userinfo
Authorization: Bearer ACCESS_TOKEN
Security Considerations
State Parameter (CSRF Protection)
Include a random state value in the authorization request and verify it matches on redirect. This prevents CSRF attacks.
Mandatory PKCE
OAuth 2.1 is expected to require PKCE for all client types. Always use PKCE in new implementations.
Token Storage
| Client Type | Recommended Storage | Notes |
|---|---|---|
| Server-side web app | Server session | Reference via HttpOnly Cookie |
| SPA | In-memory (variable) | localStorage is discouraged (XSS risk) |
| Mobile app | OS-provided secure storage | Keychain / Keystore |
redirect_uri Validation
The Authorization Server must verify exact match with pre-registered redirect_uri. Allowing wildcards or partial matches creates open redirect attack risks.
Summary
| Aspect | OAuth 2.0 | OpenID Connect |
|---|---|---|
| Purpose | Authorization (resource access control) | Authentication (user identity verification) |
| Primary token | Access token | ID Token (JWT) |
| Scopes | read, write, etc. | openid, profile, email, etc. |
| Use case | API protection | SSO, login |
Related Articles
- CISSP: Comparison of Key Security Governance Frameworks - Overview of security frameworks.
- Comparison of Major Security Models - Compares access control models that form the theoretical basis.
- Email Authentication Mechanisms (SPF, DKIM, DMARC) - Authentication technologies for email.
- Comparison and Guide to Information Security Certifications - Overview of security certifications.
References
- RFC 6749: The OAuth 2.0 Authorization Framework
- RFC 7519: JSON Web Token (JWT)
- RFC 7636: Proof Key for Code Exchange by OAuth Public Clients
- OpenID Connect Core 1.0 Specification
- OAuth 2.0 Security Best Current Practice (RFC 9700)