Sign-up stores a hash of each password. Logging in is the other half: the user sends their email and password, and the shop checks them. It's a POST, so the password travels in the body, not in a URL that ends up in logs and in the browser's history.
Checking a password: you can't undo a hash, but you can hash the typed password again with the same salt and compare. The given helper checkPassword(storedHash, typedPassword) does that and gives true or false. For example, with another password:
String stored = hashPassword("tulip7");
System.out.println(checkPassword(stored, "tulip7")); // true
System.out.println(checkPassword(stored, "tulip8")); // false
When the email has no account or the password is wrong, answer 401 with one vague message for both. Two different messages would let anyone find out which emails have an account. After two sign-ups, the test requests get:
POST /register {"email": "ana@example.com", "password": "secret123"} → 201 {"email": "ana@example.com", "id": 1}
POST /register {"email": "ben@example.com", "password": "tea4two"} → 201 {"email": "ben@example.com", "id": 2}
POST /login {"email": "ana@example.com", "password": "secret123"} → 200 {"email": "ana@example.com", "id": 1}
POST /login {"email": "ana@example.com", "password": "secret999"} → 401 {"error": "Wrong email or password"}
POST /login {"email": "nobody@example.com", "password": "secret123"} → 401 {"error": "Wrong email or password"}
POST /login {"email": "ben@example.com", "password": "secret123"} → 401 {"error": "Wrong email or password"}
POST /login {"email": "ben@example.com", "password": "tea4two"} → 200 {"email": "ben@example.com", "id": 2}
Your task: add POST /login to ShopController. Find the user by email, answer {"error": "Wrong email or password"} with 401 when there is no such user or the password doesn't match the stored hash, and otherwise answer the user's "id" and "email" with 200.
Assignment
Follow the Coding Tutorial to build the /login route.
Hint
Test rows.isEmpty() first and join the two failures with ||: when the first part is true, Java never calls rows.get(0). Cast the hash and the password to String for checkPassword.
Free plan: 30 tutor messages. PRO is unlimited.
