Start learning free

LESSON 88 OF 173 · BACKEND: USERS AND SECURITY

Tokens

Practice

HTTP has no memory: every request arrives on its own. After Ana logs in, the next request from Ana's browser carries nothing that says who is asking. The browser could send the password every time, but then the password would travel again and again. Instead, a successful login hands out a token: a random ticket that stands for the user.

The token must be impossible to guess, so it comes from the given helper randomHex, which uses Java's SecureRandom: randomHex(16) gives 16 random bytes written as 32 hexadecimal characters, a new value on every call. The shop keeps each token in a tokens table next to its user's id, so it can later look up whose ticket it is. The same idea for a coupon code:

String code = randomHex(4);   // 8 random characters, like "9f1c02ab"
db.update("INSERT INTO coupons (code, percent) VALUES (?, ?)", code, 10);

The client keeps the token and sends it with each later request, in the header Authorization: Bearer <token> ("bearer": whoever holds the ticket). Reading that header is the next lesson.

The tests first sign up Ana (id 1) and Ben (id 2). <token> stands for a random value that changes on every run:

POST /login  {"email": "ana@example.com", "password": "secret123"}  →  200  {"token": "<token>"}
POST /login  {"email": "ben@example.com", "password": "tea4two"}    →  200  {"token": "<token2>"}
POST /login  {"email": "ana@example.com", "password": "secret123"}  →  200  {"token": "<token3>"}
POST /login  {"email": "ana@example.com", "password": "secret999"}  →  401  {"error": "Wrong email or password"}

Your task: in the constructor, create a tokens table with the columns token and user_id. In login, after the 401 check, make a token with randomHex(16), store it with the user's id, and answer {"token": token}.


Assignment
Follow the Coding Tutorial to create the tokens table and make login hand out a new token on every successful login.


Hint
Every login adds a new row, even for the same user: Ana logs in twice, so Ana gets two tokens. Use user.get("id") for user_id; db.update saves the row right away.


STEP 1 OF 4
    Ctrl + Enter to check