Tokens & OAuth
When a user logs in
API keys identify an app. But what about identifying a user? When someone logs into Uber, the server needs to know which rider or driver this is. An API key can't do that, because it represents the app, not the person using it.
This is where tokens come in.
The login flow
Here's what happens when a user logs into an app. Let's walk through it step by step.
Step 1: the user sends their credentials. The app collects the email and password, then sends them to the server in a POST request:
Step 2: the server checks the credentials. It looks up the email in the Users table, verifies the password, and if everything matches, it generates a token: a long random string, similar to an API key but tied to a specific user session.
Step 3: the server sends back the token. The response looks something like:
{
"accessToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
"firstName": "Alice",
"email": "alice@acme.com"
}
Step 4: the app stores the token and includes it in every future request. From now on, every API call carries the token in the Authorization header:
The word Bearer just means "the person who carries this token." The server reads it, looks up which user it belongs to, and responds with that user's data.
Try it live
Let's go through the full flow with a real API. DummyJSON has a /auth/me endpoint that returns the current user's profile, but only if you're authenticated.
Step 1: see it fail. This endpoint needs a token. Without one, the server has no idea who "me" is. Try it:
You should get a 401 Unauthorized. The server is saying: "Who are you? You didn't tell me."
Step 2: log in and get a token. Now let's authenticate. Imagine Emily just opened the app and typed her username and password. Behind the scenes, the app sends this request:
You should get a 200 OK. Look at the response: there's an accessToken field with a long string. That's your token. Hit the Copy button that appeared below the response.
Step 3: use the token. Now paste the token you just copied into the field below and hit "Send request":
This time you should get a 200 OK with Emily's full profile (name, email, age, etc.). Same endpoint, same URL. The only difference: you included a valid token in the Authorization header.
That's the entire login flow. Credentials in, token out, token attached to every request after that.
Tokens expire (and refresh tokens)
Unlike API keys, tokens don't last forever. A typical access token expires after 15 minutes to a few hours. This is intentional: if someone steals your token, it won't work for long.
But you don't want users to re-enter their password every 15 minutes. That's where refresh tokens come in. When the server sends back an access token, it often also sends a refresh token. The refresh token is longer-lived (days or weeks). When the access token expires, the app silently uses the refresh token to get a new access token, without bothering the user.
If users in your product are getting randomly logged out, an expired token with a broken refresh flow is often the cause. That's a useful thing to mention to your engineering team.
API keys vs tokens
Both are strings sent in headers. Both authenticate requests. So what's the difference?
| API key | Token | |
|---|---|---|
| Identifies | An app | A user session |
| Created when | You sign up for a service | A user logs in |
| Expires | Usually never (until rotated) | After hours or days |
| Example | Google Maps billing your app | Uber knowing which rider is requesting a ride |
An API key says "this request comes from the Acme Dashboard app." A token says "this request comes from Alice, who logged in 20 minutes ago."
Many APIs use both. But for most APIs you'll work with, it's one or the other.
OAuth: "Sign in with Google"
You've used this a hundred times. You go to a new app, and instead of creating an account, you click "Sign in with Google." No new password to remember. A few seconds later, you're logged in.
Google is the most common provider, but the same mechanism works with Apple, Facebook, GitHub, Microsoft, X, and many others. The buttons look different, the flow is the same.
This is OAuth, and the easiest way to understand it is with an analogy.
Imagine you're visiting a company's office. You go to the front desk and say "I'm here to see Alice." The receptionist doesn't know you, so she calls Alice. Alice confirms you're expected, and the receptionist gives you a visitor badge. That badge lets you move around the building for the day, but it expires when you leave.
In OAuth:
- You are the user trying to access a new app
- The receptionist is the app you're signing into
- Alice (the trusted person inside) is Google (or Apple, or whatever provider you're signing in with)
- The visitor badge is the token the app receives
Here's the actual flow:
- You click "Sign in with Google" on the new app
- The app sends you to Google's login page
- You log in with your Google credentials (the app never sees your Google password)
- Google asks: "This app wants to access your name and email. Allow?"
- You click "Allow"
- Google sends the app a token
- The app uses that token to get your name and email from Google
The key part: the new app never sees your Google password. It only gets a limited token that Google issued. And you can revoke that token anytime by going to your Google account settings.
Why OAuth matters for PMs
If you're building a product that lets users log in, you'll likely discuss OAuth with your engineering team. Here are the conversations you might have:
"Should we support Sign in with Google?" Almost always yes for consumer products. It reduces friction at signup. Users don't need to create yet another password.
"What permissions should we request?" OAuth lets you ask for specific scopes: just the email? The profile picture? Access to their calendar? Ask for the minimum you need. Users get nervous when an app asks for too much.
Key takeaways
- Tokens identify a user session, not just an app. They're created when a user logs in.
- The login flow: send credentials, get a token, include the token in future requests.
- Access tokens expire quickly (minutes to hours). Refresh tokens let the app get new ones silently.
- OAuth ("Sign in with Google") lets users log in through a trusted provider without sharing their password with the new app.
- The app receives a limited token, not the user's actual password. The user can revoke access anytime.