OAuth2 Fundamentals

OAuth2 is the industry-standard protocol for authorization. It enables third-party applications to obtain limited access to user resources without exposing credentials.
Grant Types
Authorization Code Grant (with PKCE)
The recommended flow for public clients:
// PKCE code challenge generation
const crypto = require("crypto");
function generatePKCE() {
const verifier = crypto.randomBytes(32)
.toString("base64url");
const challenge = crypto.createHash("sha256")
.update(verifier)
.digest("base64url");
return { verifier, challenge };
}
// Authorization request
const { verifier, challenge } = generatePKCE();
const authUrl = `https://auth.example.com/authorize?
response_type=code&
client_id=app123&
redirect_uri=https://app.example.com/callback&
code_challenge=${challenge}&
code_challenge_method=S256&
scope=openid%20profile`;
// Token exchange
async function exchangeCode(code, verifier) {
const resp = await fetch("https://auth.example.com/token", {
method: "POST",
headers: { "Content-Type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "authorization_code",
code: code,
client_id: "app123",
code_verifier: verifier,
redirect_uri: "https://app.example.com/callback"
})
});
return resp.json();
}
Client Credentials Grant
For server-to-server communication:
import requests
def get_client_credentials_token(client_id, client_secret, scope):
resp = requests.post(
"https://auth.example.com/token",
data={
"grant_type": "client_credentials",
"client_id": client_id,
"client_secret": client_secret,
"scope": scope
},
headers={"Content-Type": "application/x-www-form-urlencoded"}
)
return resp.json()["access_token"]
Token Handling
Access Token Validation
// JWT verification middleware
const jwt = require("jsonwebtoken");
const jwksClient = require("jwks-rsa");
const client = jwksClient({
jwksUri: "https://auth.example.com/.well-known/jwks.json"
});
function verifyToken(req, res, next) {
const authHeader = req.headers.authorization;
if (!authHeader?.startsWith("Bearer ")) {
return res.status(401).json({ error: "Missing token" });
}
const token = authHeader.split(" ")[1];
jwt.verify(token, (header, callback) => {
client.getSigningKey(header.kid, (err, key) => {
callback(err, key.getPublicKey());
});
}, {
algorithms: ["RS256"],
issuer: "https://auth.example.com",
audience: "https://api.example.com"
}, (err, decoded) => {
if (err) return res.status(401).json({ error: "Invalid token" });
req.user = decoded;
next();
});
}
Refresh Token Rotation
def rotate_refresh_token(old_token):
Verify the old refresh token
token_data = verify_refresh_token(old_token)
Revoke the old token
revoke_token(old_token)
Issue new tokens
new_access = create_access_token(token_data["user_id"])
new_refresh = create_refresh_token(token_data["user_id"])
return {
"access_token": new_access,
"refresh_token": new_refresh,
"expires_in": 3600
}
Best Practices
oauth2_best_practices:
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- Always use PKCE for public clients
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- Use short-lived access tokens (15-60 minutes)
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- Implement refresh token rotation
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- Use RS256 or ES256 for JWT signing
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- Validate all claims (iss, aud, exp, nbf)
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- Store tokens securely (httpOnly cookies, secure storage)
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- Implement token revocation
\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\- Log all token issuance and usage
Conclusion
OAuth2 is complex but essential for modern authentication. PKCE makes authorization code flow safe for single-page apps. Use short-lived access tokens with refresh token rotation. Always validate tokens thoroughly on the server side. Keep your JWKS endpoint secure and rotate signing keys regularly.
Enjoy this article? Share your thoughts, questions, or experiences in the comments below — your insights help other readers too.
Join the discussion ↓