Start learning free

LESSON 97 OF 173 · BACKEND: USERS AND SECURITY

Secrets Live Outside the Code in Go

Practice

Until now, the shop's secrets were written in its code, like the admin's password. But code travels: to the whole team, into old copies, onto GitHub. A secret that everyone who reads the code knows is no secret.

Secrets belong in environment variables: values the server gives the program when it starts, outside the code. In Go, os.Getenv(name) reads one, and gives an empty string "" when it isn't set. cmp.Or gives back the first of its values that isn't empty, so put the variable first and a default second:

dbFile := cmp.Or(os.Getenv("DB_FILE"), "shop.db")

For a secret, the default must be safe: a random value from the shop's helper randomHex(16) that nobody can know. If a server forgets to set the admin's password, nobody can log in as admin, which is much safer than everyone who has seen the code being able to. Settings that aren't secret but change from place to place, like the address of the shop's website, come from the environment too. A Go const must be known when the code compiles, so shopSite becomes a var.

The grader starts the shop with ADMIN_PASSWORD set to env-admin-pass-456 and SHOP_SITE set to https://shop.example.com. Your code must answer:

POST /login  {"email": "admin@example.com", "password": "admin-pass-123"}      →  401  {"error": "Wrong email or password"}
POST /login  {"email": "admin@example.com", "password": "env-admin-pass-456"}  →  200  {"token": "<admin>"}
GET /me  (the session cookie from that login)  →  200  {"email": "admin@example.com", "id": 1, "role": "admin"}
POST /products  {"name": "Desk", "price": 120}  (admin's token)  →  201  {"id": 9, "name": "Desk", "price": 120}
GET /products/1  Origin: https://shop.example.com  →  200, Access-Control-Allow-Origin: https://shop.example.com
GET /products/1  Origin: http://localhost:3000     →  200, no Access-Control-Allow-Origin

Your task: in newApp, set adminPassword from ADMIN_PASSWORD with randomHex(16) as its default, and declare shopSite as a var read from SHOP_SITE, with "http://localhost:3000" as its default. cmp, os and randomHex are already there.


Assignment
Follow the Coding Tutorial to read the admin's password and the shop's website from the environment.


Hint
Each value is one cmp.Or(os.Getenv(name), default). The default is what the program uses on your computer and in tests, where nothing is set, so for a secret it must be something nobody can guess.


STEP 1 OF 2
    Ctrl + Enter to check

    Sec Secrets Config 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