OAuth flows are a minefield, and PKCE is the safe default for public clients. I generate a verifier, derive a challenge, store the verifier in a short-lived session, and then exchange the authorization code for tokens. The key detail is treating the verifier like a secret: keep it server-side when possible, or store it in a secure, short-lived cookie if you’re doing a pure browser flow. I also validate state to prevent CSRF. In production I prefer a well-maintained OAuth library, but understanding the moving parts helps debug ‘works locally but not in prod’ issues around redirect_uri, scopes, and token lifetimes.