Profile    Mohammed Shiroz Status   Loading  
Logo
Share This
Back to blog
Filter by:
Tags
//Article title

OAuth 2.0 Explained Without the Jargon: The Valet Key Guide

About Post

You pull up at a fancy hotel. The valet holds out a hand for your keys. You hesitate, because that key also opens the boot, the glovebox and, if you're unlucky, your house.

Some cars solve this with a valet key: it starts the engine and opens the driver's door, and that's it. The valet can park the car. They can't read your mail.

That's OAuth 2.0. Everything else in the spec is detail about how to hand over the valet key safely. Let's go through it without the jargon, then add back just enough jargon to read the docs.

The problem OAuth solves

Years ago, if a photo printing website wanted your pictures from another service, it asked for your username and password for that service. Then it logged in as you. With full access. Forever, or until you changed your password and broke every other app that did the same thing.

OAuth replaces "give me your password" with "let the service you trust give me a limited key". The printing site never sees your password. It gets a token that can read photos, maybe only for a while, and you can take it back any time.

The cast of characters

OAuth has four roles. Here they are in valet terms:

OAuth nameValet versionPhoto example
Resource ownerYou, the car ownerYou, the person with the photos
ClientThe valetThe photo printing website
Authorization serverThe hotel desk that issues valet keysThe photo service's login and consent screen
Resource serverThe carThe photo service's API

The authorization server and resource server often belong to the same company, but they're different jobs: one hands out keys, the other checks them.

The flow you should use: authorization code with PKCE

OAuth has several "flows". For almost every app today, web, mobile or single-page, the answer is the authorization code flow with PKCE. Here it is, step by step.

Step 1: the app sends you to the authorization server

You click "Import from PhotoCloud". The printing site redirects your browser to PhotoCloud with a URL like this:

https://photocloud.example/authorize
  ?response_type=code
  &client_id=print-shop
  &redirect_uri=https://print.example/callback
  &scope=photos.read
  &state=af0ifjsldkj
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  &code_challenge_method=S256

In plain words: "Hi, I'm the print shop. I'd like to read this person's photos. Send them back to this address afterwards."

Step 2: you log in and consent

You log in on PhotoCloud's own page, not the print shop's. That's the crucial part: your password only ever goes to the service that owns it. PhotoCloud shows "Print Shop wants to view your photos" and you click Allow.

Step 3: you're sent back with a short-lived code

PhotoCloud redirects to https://print.example/callback?code=...&state=af0ifjsldkj. The code is not the key yet. It's more like a claim ticket: short-lived and single-use. The app checks that state matches what it sent, which protects against someone forging the callback.

Step 4: the app swaps the code for tokens

The print shop's backend calls PhotoCloud directly, server to server, and exchanges the code for an access token (and usually a refresh token). Then it calls the API with Authorization: Bearer <access token>. Valet key in hand.

So what is PKCE, and why does it matter?

PKCE (Proof Key for Code Exchange, pronounced "pixie") closes a gap in step 3. The code travels through the browser, and on mobile it travels through a redirect that another app could, in some cases, intercept. If an attacker grabs the code, could they swap it for tokens?

PKCE says no. Before step 1, the app invents a random secret, the code verifier, and keeps it. It sends only a hash of it, the code challenge, in the first URL. In step 4, it must present the original verifier. The authorization server hashes it and compares. A stolen code without the verifier is useless.

It was designed for mobile and single-page apps, which can't keep a client secret (anyone can unpack your app and read it). Current best practice is to use PKCE for every client, including server-side apps that also have a secret.

Scopes and tokens, briefly

  • Scopes are the valet key's limits: photos.read, not photos.delete. Ask for the smallest set you need. Users read consent screens more than you'd think, and a scary list gets a "Deny".
  • Access tokens are short-lived. If one leaks, the damage window is small.
  • Refresh tokens are long-lived and used only to get new access tokens from the authorization server. Store them like passwords: server-side or in secure device storage, never in localStorage.

The old implicit flow, which returned the token directly in the browser URL, is no longer recommended. If a tutorial uses response_type=token, find a newer tutorial.

OAuth vs OpenID Connect: the most common confusion

Here's the thing that trips everyone up: OAuth is about access, not identity. A valet key proves you're allowed to drive the car. It doesn't tell the hotel who you are.

Plenty of apps used OAuth for "Log in with X" anyway, by calling some profile endpoint with the access token. Every provider did it differently. OpenID Connect (OIDC) standardises it: a thin layer on top of OAuth that adds an ID token, a signed JWT that says who the user is, which app it was issued for, and when.

OAuth 2.0OpenID Connect
Question it answers"What can this app access?""Who is this user?"
Main tokenAccess tokenID token (plus access token)
Typical useCalling an API on the user's behalf"Sign in with Google" style login
Scope you'll seeWhatever the API definesopenid, profile, email

If you're building login, you want OIDC. If you're calling someone's API for a user, you want OAuth. "Sign in with Google" is both at once.

The rules worth memorising: authorization code flow, always with PKCE. Validate state. Ask for minimal scopes. Short-lived access tokens, carefully stored refresh tokens. OAuth for access, OIDC for identity.

In Laravel

You rarely implement this by hand. As a client ("log in with GitHub"), Socialite handles the redirects, state and token exchange. As a provider (other apps logging in through yours), Passport is a full OAuth 2 server. If you only need tokens for your own SPA or mobile app, you probably don't need OAuth at all, and Sanctum is the simpler fit.

Knowing the flow still pays off. When a callback fails with "invalid_grant" at 6 pm, the person who understands steps 1 to 4 fixes it in minutes.

What was the OAuth concept that took you the longest to really understand? For me it was accepting that OAuth, on its own, isn't a login protocol.

Comments (0)
Leave your review

Thanks for your valuable comments. Your comments has been updated and appreciate your getting in touch...

01. About Shiroz

Mohammed Shiroz

Hi, I'm Mohammed Shiroz, a software engineer and AI enthusiast from Sri Lanka who turns ideas into intelligent, real-world solutions. With over 9 years of hands-on experience, I currently lead real estate ERP development at Kate Group, a...

03.My Projects

04. Categories

Ready To order Your Project ?

Get in Touch
Close