OAuth2 is deceptively simple conceptually, yet its implementation details can lead to surprisingly complex security vulnerabilities if not handled with extreme care.
Let’s see it in action. Imagine a user, Alice, wants to grant a third-party application, "PhotoEditor," access to her photos stored on "PhotoCloud."
-
Alice initiates the process: Alice clicks "Connect PhotoEditor to PhotoCloud" in PhotoEditor. PhotoEditor redirects Alice’s browser to PhotoCloud’s authorization server with specific parameters:
client_id:photoeditor_app_123(PhotoEditor’s unique identifier)redirect_uri:https://photoeditor.com/callback(Where PhotoCloud should send Alice back)response_type:code(Requesting an authorization code)scope:read_photos write_photos(What permissions PhotoEditor is asking for)state:a_random_string_to_prevent_csrf(A unique, unguessable value)
-
PhotoCloud asks for consent: PhotoCloud logs Alice in (if she’s not already) and presents her with a consent screen: "PhotoEditor wants to access your photos. Allow? [Allow] [Deny]". Alice clicks "Allow."
-
Authorization Code Grant: PhotoCloud generates a short-lived, one-time-use authorization
code(e.g.,XYZ123ABC) and sends Alice’s browser back to PhotoEditor’sredirect_uri, including thecodeand the originalstatevalue:https://photoeditor.com/callback?code=XYZ123ABC&state=a_random_string_to_prevent_csrf. -
Token Exchange: PhotoEditor’s backend server receives this request. It then makes a direct, server-to-server request to PhotoCloud’s token endpoint. This request includes:
grant_type:authorization_codecode:XYZ123ABCredirect_uri:https://photoeditor.com/callback(Must match the original)client_id:photoeditor_app_123client_secret:a_very_secret_password_for_photoeditor(This is why the backend is crucial; never expose this in the browser!)
-
Access Token Issued: PhotoCloud verifies the
client_id,client_secret,code, andredirect_uri. If valid, it issues anaccess_token(e.g.,eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...) and potentially arefresh_token. These are sent back to PhotoEditor’s backend. -
API Access: PhotoEditor’s backend now uses the
access_tokento make requests to PhotoCloud’s API on Alice’s behalf. It includes the token in theAuthorizationheader:Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.... PhotoCloud validates theaccess_tokenand, if valid and within scope, returns Alice’s photos.
This is the "Authorization Code Grant" flow, the most common and secure for web applications.
The core problem OAuth2 solves is delegating access without sharing credentials. Instead of giving PhotoEditor Alice’s PhotoCloud username and password (which would let PhotoEditor do anything Alice can do), Alice grants PhotoEditor specific, limited permissions (scopes) for a limited time (access_token lifetime). The state parameter is crucial for preventing Cross-Site Request Forgery (CSRF) by ensuring the callback request originated from the same user session that initiated the authorization request.
The access_token is usually a JWT (JSON Web Token). It contains claims like the iss (issuer, PhotoCloud), aud (audience, PhotoEditor), sub (subject, Alice’s user ID), exp (expiration time), and scope. The client application can inspect the token’s claims, but it must not trust them implicitly; the authorization server is the ultimate authority. The refresh_token is a long-lived token used to obtain new access_tokens when the current one expires, without requiring Alice to re-authorize.
The most counterintuitive aspect of OAuth2, and a frequent source of security flaws, is the role of the redirect_uri. It’s not just a convenience; it’s a critical security control. The authorization server must strictly validate that the redirect_uri provided in the token exchange request exactly matches one of the pre-registered URIs for that client_id. If this validation is weak, an attacker could trick the authorization server into sending the authorization code to their own malicious redirect_uri, effectively stealing the code and then exchanging it for an access token.
The next logical step in understanding OAuth2 is exploring how to secure the refresh_token and handle token revocation.