Node.js › Authentication & Authorization

How does the OAuth 2.0 Authorization Code flow work, and what role does Node.js typically play as the client or the resource server?

Advanced

Answer

In the Authorization Code flow, a user is redirected to the authorization server (like Google) to log in and consent; the authorization server redirects back to the application with a temporary authorization code, which the application's backend (never the browser, to keep it confidential) exchanges directly with the authorization server for an access token (and often a refresh token) -- this two-step exchange, with the code exchange happening server-to-server, is what prevents the access token from ever being exposed in browser history or a redirect URL. A Node.js backend commonly plays the role of the 'client' performing this exchange, or the 'resource server' validating access tokens presented by other clients.
// Step 2: exchanging the authorization code for tokens (server-to-server)
const response = await fetch('https://oauth-provider.com/token', {
  method: 'POST',
  body: new URLSearchParams({
    grant_type: 'authorization_code',
    code: req.query.code,
    redirect_uri: REDIRECT_URI,
    client_id: CLIENT_ID,
    client_secret: CLIENT_SECRET, // kept only on the server, never sent to the browser
  }),
});
const { access_token } = await response.json();
Real-world example A Node.js application implements 'Sign in with Google' using Passport's OAuth strategy, where the backend handles the authorization-code exchange with Google's token endpoint directly, ensuring the application's client secret is never exposed to the browser at any point in the flow.

Common follow-ups: Why is the Authorization Code flow considered more secure than the older Implicit flow for a server-side application?;What is PKCE, and why is it now recommended even for confidential clients?