Unit 8: APIs and how modern apps talk · Lesson 2 of 5 · 20 min

Calling an API with a token

Get a bearer token, send it the right way and review what the API returns about you.

mission

You are
The analyst reviewing the shop's API.
Situation
The profile endpoint /api/v1/me is the first thing the mobile app calls after sign-in.
Goal
Call it with and without a token and review every field it returns.
Hand in
The fields /api/v1/me returns and any that should not be there.

A JWT, three parts

eyJhbGciOi....eyJzdWIiOi....c2lnbmF0dX...
  1. 1eyJhbGciOi...header: algorithm
  2. 2.eyJzdWIiOi...payload: who and until when
  3. 3.c2lnbmF0dX...signature: proves it was not changed
01

Without a token

learner@web-lab
curl -si http://127.0.0.1:8000/api/v1/me | grep -iE '^(HTTP|www-authenticate)'
HTTP/1.1 401 Unauthorized
WWW-Authenticate: Bearer realm="shop"

you should see 401 and a WWW-Authenticate header naming the scheme the API expects.

02

Get a token

Keep the token in a file, not in a URL.

learner@web-lab
curl -s -d @shop-account.txt http://127.0.0.1:8000/api/token | jq -r .access_token > token.txt
wc -c < token.txt
214

you should see A token of a couple of hundred characters.

03

Call the profile endpoint

learner@web-lab
curl -s -H "Authorization: Bearer $(cat token.txt)" http://127.0.0.1:8000/api/v1/me | jq .
{
  "user": "learner",
  "email": "learner@shop.internal",
  "role": "customer",
  "password_hash": "pbkdf2_sha256$600000$q2Vt8k1sR9mZ$ObOoXw2Lu84Fh+C0wkMbWgSyKaZD+KLIFo3ynohSNYk="
}

you should see Your user, email and role, and one field that has no business leaving the server.

04

List the fields

learner@web-lab
curl -s -H "Authorization: Bearer $(cat token.txt)" http://127.0.0.1:8000/api/v1/me | jq -r 'keys[]'
email
password_hash
role
user

you should see Four fields. The password hash is excessive data exposure: the app never needs it.

defender tip APIs often return whole database rows and leave hiding to the app. Review what the API sends, not what the screen shows.

The profile response

Today
return user_row

Every column, hash included.

Fix
return {"user": u.name, "email": u.email, "role": u.role}

An explicit allowlist of fields.

What a defender takes away

  1. 1Send tokens in the Authorization header, never in the URL.
  2. 2401 with WWW-Authenticate is the right answer to a missing token.
  3. 3Review raw API responses for fields the client never uses.

Questions

0 of 3 solved

Answer each one from what you find on your lab machine.