Start learning free

LESSON 83 OF 173 · BACKEND: USERS AND SECURITY

Who May Change Things? in Go

Practice

Right now anyone can add a product to the shop: POST /products saves whatever it receives and never asks who is calling. A real shop lets everyone read its products, but only its owner may change them. The simplest way to tell the owner apart: the owner knows a secret, the admin key, and sends it with every request that changes something.

The key travels in a header: a name and a value that go with the request, next to the body. In Go you read one with r.Header.Get("Name"). It gives the empty text "" when the request doesn't have that header. Here a made-up route picks its greeting from a header:

app.HandleFunc("GET /hello", func(w http.ResponseWriter, r *http.Request) {
	lang := r.Header.Get("X-Language")
	if lang == "fr" {
		writeJSON(w, 200, map[string]string{"message": "Bonjour"})
		return
	}
	writeJSON(w, 200, map[string]string{"message": "Hello"})
})

Notice the return: writeJSON sends an answer, but the handler keeps running until it reaches a return or its end. When the key is missing or wrong, the shop answers 401 Unauthorized, which means "I don't know who you are", and saves nothing. With the right key, the product is added as before. These are the requests your code must answer:

POST /products  {"name": "Vase", "price": 18}  (no key)                    →  401  {"error": "Missing or unknown key"}
POST /products  {"name": "Vase", "price": 18}  X-Admin-Key: let-me-in      →  401  {"error": "Missing or unknown key"}
POST /products  {"name": "Vase", "price": 18}  X-Admin-Key: admin-key-123  →  201  {"id": 9, "name": "Vase", "price": 18}
GET /products/9   →  200  {"category": null, "id": 9, "name": "Vase", "price": 18, "stock": 0}
GET /products/10  →  404  {"error": "Product not found"}

Your task: store the secret "admin-key-123" in a constant adminKey. At the start of the POST /products handler, read the X-Admin-Key header into key, and when it isn't the admin key, answer {"error": "Missing or unknown key"} with the status 401 and return before anything is saved.


Assignment
Follow the Coding Tutorial to protect POST /products with the admin key.


Hint
Put the check before the body is decoded and the INSERT: once the row is saved, a 401 comes too late. Don't forget the return after the 401, or the handler goes on and saves the product anyway. One != covers both cases, because a missing header gives "", and "" isn't the key either.


STEP 1 OF 5
    Ctrl + Enter to check

    Auth Admin Key in Go

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