Start learning free

LESSON 89 OF 173 · BACKEND: USERS AND SECURITY

Who Am I? in C#

Practice

After logging in, a client holds a token. On every later request it sends the token back in the Authorization header, written as the word Bearer, a space, then the token. The shop looks the token up in the tokens table to find out who is calling.

Many routes will need that answer, so the lookup goes in a helper method that any route can call. Two tools help: request.Headers["…"].ToString() gives "", an empty text, when the header is missing, and a JOIN goes from a row in one table to the row it points to in another. Both on a made-up example:

var lang = request.Headers["Accept-Language"].ToString();   // "" when the header is missing
var shortLang = lang.Replace("-US", "");                    // "en-US" becomes "en"
var cmd = new SqliteCommand("SELECT products.name FROM orders JOIN products ON products.id = orders.product_id WHERE orders.id = $id", db);

GET /me answers the logged-in user's id and email. With no token, or a token the shop never gave out, it answers 401. Below, <token> and <token2> stand for the random tokens the logins answered:

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  {"token": "<token>"}
POST /login  {"email": "ben@example.com", "password": "tea4two"}    →  200  {"token": "<token2>"}
GET /me  Authorization: Bearer <token>   →  200  {"email": "ana@example.com", "id": 1}
GET /me  Authorization: Bearer <token2>  →  200  {"email": "ben@example.com", "id": 2}
GET /me  (no header)  →  401  {"error": "Login required"}
GET /me  Authorization: Bearer 0123456789abcdef0123456789abcdef  →  401  {"error": "Login required"}

Your task: write a helper CurrentUser(request) that reads the token from the Authorization header and returns its user's id and email as a dictionary, or null. Then add GET /me: answer {"error": "Login required"} with 401 when there is no user, otherwise the user as JSON.


Assignment
Follow the Coding Tutorial to write the CurrentUser helper and the /me route that uses it.


Hint
.ToString() gives "" for a missing header, so .Replace works even then. An empty or unknown token matches no row: reader.Read() gives false, the helper returns null, and that is the 401 case.


STEP 1 OF 12
    Ctrl + Enter to check

    Auth Me in C#

    Keep going with C#1,600+ step-by-step lessons, from your first line of code to coding interviews. Free to start.
    Start learning free