Why must the client send its client_secret to the /token endpoint, and why is the secret never sent through the browser?
The client secret proves the token request really comes from the registered app, and it's sent only server-to-server so it never leaks through the browser.
In step 6 the client posts to /token: authorization code + client ID + client secret. The authorization server validates all three (step 7) before issuing tokens.
The client_secret is the application's password — it authenticates the app itself (not the user). If anyone could redeem an authorization code, a stolen code would be enough to get tokens. Requiring the secret means only the genuine app can complete the exchange.
Crucially this happens in the back channel (the app's server → the AS), never via a browser redirect. A secret that travelled through the browser could be read by the user, extensions, history, or a proxy — defeating its purpose.
Tip: Public clients that can't keep a secret (single-page apps, mobile) use PKCE instead of a client secret to secure the code exchange — the approach recommended in current OAuth guidance.
Go deeper:
RFC 7636 — Proof Key for Code Exchange (PKCE) — how public clients secure the code exchange without a client secret.