Tema
/
Interneto svetainių serverio dalies kūrimas GO
📖 Teorija

El. pašto sąsaja ir atstatymo dizainas

Autentifikacijoje liko viena spraga: pamiršęs slaptažodį vartotojas užrakintas amžinai. Ši pamoka stato slaptažodžio atstatymą — o atstatymo nuorodai išsiųsti, el. pašto sluoksnį, kurį vėliau perpanaudosi pasirašytojų kvietimams.

El. paštas už sąsajos. Tikram el. paštui siųsti reikia API rakto ir mokamos paslaugos — baisi kliūtis besimokančiam. Tad el. paštas gyvena už vieno metodo sąsajos:

type Sender interface {
	Send(ctx context.Context, msg Message) error
}

Dvi realizacijos, parenkamos konfigūracijos:

  • ConsoleSender (dev numatytoji) nieko nesiunčia — ji spausdina laišką su nuoroda į tavo terminalą. Paleidi visą atstatymo srautą, nukopijuoji nuorodą iš log'o ir užbaigi — be API rakto, be paskyros, be nieko.
  • ResendSender (prod) POST'ina į Resend API. Vienas HTTP kvietimas, jokio SDK.

email.New parenka: bet kas kita nei "resend" duoda konsolės siuntėją. Dev — nulis konfigūracijos; prod — vienas aplinkos kintamasis. Tai ta pati „sąsaja su dev realizacija ir prod realizacija" siūlė kaip vėliau storage.Store„produkcijoje tai tikras tiekėjas; čia jis spausdina į terminalą."

Maža klaida su tikra pasekme — kodėl konsolės siuntėjas rašo tiesiai į stdout. Akivaizdus būdas spausdinti laišką — log.Info(...). Nedaryk. slog ekranuoja naujas eilutes į raidinį \n — tad daugiaeilis laiškas su atstatymo nuoroda subyra į vieną neskaitomą eilutę ...\nhttp://...\n.... Studentas, negalintis perskaityti nuorodos, negali užbaigti pamokos. Tad ConsoleSender rašo tiesiai į os.Stdout su fmt.Fprintf, piešdamas švarią dėžutę su tikromis eilučių pertraukomis. Smulkmena; be jos visas srautas nenaudojamas.

Atstatymo žetonas — vėl sesijų šablonas. Atstatymo nuoroda neša atsitiktinį žetoną; duomenų bazė saugo tik jo SHA-256, vienkartinį (used_at) ir galiojantį (1 val.). Pavogta kopija neduoda veikiančių nuorodų. O užbaigus atstatymą įvyksta trys dalykai iš eilės: pažymėti žetoną panaudotu, panaikinti visus kitus likusius atstatymo žetonus ir ištrinti visas to vartotojo sesijas. Slaptažodžio keitimas turi atjungti visur — jei kažkas atstatė tavo slaptažodį, bet kuri jo atverta sesija miršta kartu.

Nuskaitymo apsauga, vėl. „Pamiršau slaptažodį" rodo tą patį patvirtinimą nepriklausomai, ar el. paštas egzistuoja„jei paskyra egzistuoja, išsiuntėm nuorodą." Jokio formos zondavimo, kad sužinotum, kas turi paskyrą.

Ši pamoka:

  1. Atstatymo žetonų lentelė + užklausos + token.go generatorius.
  2. email.Sender sąsaja ir jos dvi realizacijos, sujungtos.
  3. Forgot → reset srautas nuo pradžios iki galo — užbaigtas visiškai iš konsolės.