Skip to main content
API Security Tutorial
CHAPTER 07 Intermediate

OAuth 2.0 Security Basics

Updated: May 13, 2026
25 min read

# CHAPTER 7

OAuth 2.0 Security Basics

1. Introduction

You have built a secure API using JWTs, but suddenly your product manager asks for a new feature: "Allow users to log in using their Google or Facebook accounts." Furthermore, they want your application to be able to post tweets to the user's Twitter account. How do you do this securely without asking the user to give you their Twitter password? The answer is OAuth 2.0. In this chapter, we will demystify the OAuth 2.0 framework, explain the Authorization Code flow, and discuss how to secure external API integrations.

2. Learning Objectives

By the end of this chapter, you will be able to:
  • Explain the primary purpose of OAuth 2.0 (Delegated Authorization).
  • Identify the four roles in OAuth (Resource Owner, Client, Authorization Server, Resource Server).
  • Understand the Authorization Code Flow step-by-step.
  • Recognize the security risks of misconfigured Redirect URIs.
  • Implement secure state parameters to prevent CSRF attacks.

3. Beginner-Friendly Explanation

Imagine you stay at a fancy hotel (Google). You want to order room service via an external food delivery app (Your App). The food delivery app needs to know your room number to deliver the food, but you absolutely DO NOT want to give the delivery app the master key to your hotel room!

OAuth 2.0 is the solution:

  1. 1. The Delivery App redirects you to the Hotel Front Desk.
  1. 2. The Hotel Front Desk asks you, "Do you authorize this Delivery App to know your room number?"
  1. 3. You say "Yes."
  1. 4. The Hotel gives the Delivery App a temporary, limited "Access Badge" (a Token).
  1. 5. The Delivery App uses that badge to deliver the food.
They never saw your master key (your password), and the badge only allows them to access your room number, nothing else.

4. Real-World Attack Scenarios

  • The Redirect URI Hijack: A developer misconfigures their OAuth setup, allowing any Redirect URL. An attacker tricks a victim into clicking a "Log in with Google" link. When Google issues the authorization code, it redirects the victim to the *attacker's* website instead of the legitimate app, allowing the attacker to steal the code and take over the account.
  • CSRF Login Attack: An attacker initiates an OAuth login with *their own* account, intercepts the callback, and tricks a victim into clicking a link containing that callback. The victim is forcefully logged into the attacker's account, potentially exposing the victim's payment data to the attacker.

5. The Four Roles in OAuth 2.0

Before looking at code, you must understand the vocabulary:
  1. 1. Resource Owner: The User (You).
  1. 2. Client: The Application requesting access (Your PHP/React app).
  1. 3. Authorization Server: The system verifying the user (Google's Login Server).
  1. 4. Resource Server: The system holding the data (Google Contacts API).

6. The Authorization Code Flow (Secure Standard)

This is the most common and secure flow for web applications.
  1. 1. User clicks "Login with Google".
  1. 2. Redirect: Your PHP app redirects the user to Google's login page, passing your client_id and a redirect_uri.
  1. 3. Consent: The user logs into Google and clicks "Allow".
  1. 4. The Code: Google redirects the user back to your PHP app's redirect_uri with a temporary code in the URL (e.g., ?code=xyz123).
  1. 5. The Exchange (Backend to Backend): Your PHP server securely takes that code, adds your secret client_secret, and sends a hidden POST request directly to Google.
  1. 6. The Token: Google verifies the code and secret, and responds with the final access_token.

7. HTTP Examples (The Exchange)

Step 5 is critical because the client_secret is never exposed to the user's browser.
http
123456789
POST /oauth2/v4/token HTTP/1.1
Host: www.googleapis.com
Content-Type: application/x-www-form-urlencoded

code=xyz123&
client_id=YOUR_CLIENT_ID&
client_secret=YOUR_SUPER_SECRET_DO_NOT_SHARE&
redirect_uri=https://yourapp.com/callback&
grant_type=authorization_code

8. PHP Examples (The State Parameter)

To prevent Cross-Site Request Forgery (CSRF) during the OAuth flow, you must use a state parameter.
php
12345678910111213141516171819202122
<?php
// 1. Generate a random state string and save it in the user's session
$state = bin2hex(random_bytes(16));
$_SESSION[&#039;oauth_state'] = $state;

// 2. Append it to the Google Login URL
$login_url = "https://accounts.google.com/o/oauth2/auth?" . http_build_query([
    &#039;client_id' => '...',
    &#039;redirect_uri' => '...',
    &#039;response_type' => 'code',
    &#039;state' => $state // Send state to Google
]);
header("Location: $login_url");
?>

<?php
// 3. In your Callback file, VERIFY the state returned by Google
if (!isset($_GET[&#039;state']) || $_GET['state'] !== $_SESSION['oauth_state']) {
    die("Security Error: Invalid State Parameter. Potential CSRF Attack.");
}
// Proceed to exchange the code for a token...
?>

9. Scopes

OAuth relies heavily on "Scopes". Scopes limit exactly what the access token can do. If your app only needs to read a user's email address, you request scope=email. If you accidentally request scope=mail.read_write (access to all their emails), the user will likely get scared and deny the request, or worse, your app becomes a massive liability if hacked.

10. Best Practices

  • Strict Redirect URIs: In your Google/Facebook developer console, explicitly define the exact, full URL of your callback (e.g., https://yourapp.com/oauth/callback). Never use wildcards like *.yourapp.com.
  • Keep Secrets Secret: Treat your OAuth client_secret exactly like a database password. Never expose it in frontend JavaScript or Mobile App code.
  • Use Libraries: Do not write OAuth flows from scratch. Use established packages like PHP League's oauth2-client.

11. Common Mistakes

  • Implicit Flow: Older tutorials might teach the "Implicit Flow", where Google sends the access_token directly in the URL hash. This is now considered insecure and deprecated for web apps. Always use the Authorization Code Flow.
  • Ignoring Token Expiration: OAuth access tokens expire quickly. You must write logic to use the refresh_token to get a new access token without forcing the user to log in again.

12. Security Checklists

OAuth Implementation Checklist:
  • [ ] Is the Authorization Code Flow being used (instead of Implicit)?
  • [ ] Is the state parameter generated, stored in a session, and strictly verified upon callback?
  • [ ] Is the client_secret stored securely on the backend?
  • [ ] Are the requested scopes strictly limited to the absolute minimum required?
  • [ ] Are Redirect URIs strictly whitelisted in the identity provider's dashboard?

13. Mini Exercises

  1. 1. In the OAuth framework, what term is used to describe the User?
  1. 2. Why is the client_secret never sent to the user's browser?

14. Practice Challenges

Challenge: Go to the Google Cloud Console or GitHub Developer settings and register a new "OAuth Application". Look at the required fields. Notice how they force you to define a specific "Callback/Redirect URI" and provide you with a Client ID and Client Secret.

15. MCQs with Answers

Question 1

What is the primary purpose of OAuth 2.0?

Question 2

In the OAuth 2.0 Authorization Code flow, what crucial parameter must be used to prevent Cross-Site Request Forgery (CSRF) attacks?

Question 3

Why is the "Implicit Flow" considered insecure for modern applications?

16. Interview Questions

  • Q: Explain the steps of the OAuth 2.0 Authorization Code flow as if I were a junior developer integrating "Login with Google".
  • Q: What is the state parameter in OAuth, and what specific attack does it prevent?
  • Q: What is the difference between an Access Token and a Refresh Token in the context of OAuth?

17. FAQs

Q: What is the difference between OAuth 2.0 and OpenID Connect (OIDC)? A: OAuth 2.0 is strictly for *Authorization* (granting access to data). OpenID Connect is an identity layer built on top of OAuth 2.0 that handles *Authentication* (verifying who the user is). When you use "Log in with Google" to identify a user, you are technically using OpenID Connect!

18. Summary

In this chapter, we unpacked the complexities of OAuth 2.0. We learned that OAuth is a framework for delegated authorization, allowing our app to act on a user's behalf without ever seeing their password. We walked through the secure Authorization Code flow, emphasizing that the final token exchange must happen server-to-server to protect the Client Secret. Finally, we highlighted the critical necessity of the state parameter to thwart CSRF attacks.

19. Next Chapter Recommendation

We know who the user is, but what are they allowed to do? Can they delete another user's account? Proceed to Chapter 8: Authorization and Access Control to build the security walls that govern user permissions.

Finish this Chapter

Save your progress on your learning path and prepare for coding interview challenges.

Discussion

Join the discussion

Log in or create a free account to participate.

Sort: ·