Įjunk apsaugą — ir pataikyk į 403
Pirma priklausomybė:
go get github.com/gorilla/csrf
Trys failai kaip skirtukai, priklausomybių tvarka: config.go → main.go → router.go — paslaptis žetonui, išvestas raktas ir pats middleware. Visi trys — pakeitimai.
1. internal/config/config.go (modify) — SessionSecret, skaitomas iš SESSION_SECRET. Dev aplinkoje jis krenta į fiksuotą nesaugią reikšmę, kad viskas veiktų iš karto; produkcijoje jis privalomas (apsauga grąžina klaidą, jei jo nėra). Visa kita perkelta.
2. cmd/signflow/main.go (modify) — išvesk stabilų 32 baitų raktą iš paslapties, tad valdyti reikia tik vienos paslapties:
csrfKey := sha256.Sum256([]byte("csrf:" + cfg.SessionSecret))
// ...
Handler: h.Router(staticFS, csrfKey[:]), // ← Router dabar ima raktą
3. internal/handlers/router.go (modify) — pati apsauga:
csrfMW := csrf.Protect(
csrfKey,
csrf.Secure(h.Cfg.IsProd()), // Secure slapukas tik produkcijoje
csrf.FieldName("gorilla.csrf.Token"), // paslėptas laukas, kurį nešios formos
)
r.Use(csrfMW)
Štai ir viskas — CSRF dabar užtikrinama kiekvienam POST.
Patikrink — ir žiūrėk, kaip lūžta. Sugeneruok ir paleisk, tada bandyk prisijungti:
go run ./cmd/signflow
Atsidaryk http://localhost:8080/login, įvesk duomenis, pateik. Vietoj skydelio:
Forbidden - referer not supplied
403. Ant tavo paties prisijungimo formos. Su teisingais duomenimis. O pranešimas — „referer not supplied" — nieko nesako apie tai, kas iš tikro negerai. Tai klaida, į kurią kiekvienas Go kūrėjas pataiko kartą ir sudegina popietę.
Patvirtink ir iš komandinės eilutės:
$ curl -si -X POST localhost:8080/login -d 'email=a@b.co&password=x' | head -1
HTTP/1.1 403 Forbidden
Kol kas netaisyk. Pasėdėk su tuo sekundę. Tavo forma neturi žetono lauko, ir esi ant http:// — bet klaida visai nemini žetonų; ji skundžiasi referer. Tai užuomina. Kitas žingsnis paaiškina, kodėl būtent, ir pataiso dviem ėjimais.