Tema
/
Interneto svetainių serverio dalies kūrimas GO

Atstatymo žetonų saugykla

Penki failai kaip skirtukai, priklausomybių tvarka: 00003_password_reset_tokens.sqlpassword_resets.sqlusers.sqlsessions.sqltoken.go (lentelė, jos užklausos ir du esami užklausų failai, kurie auga). Tada sqlc generate.

1. db/migrations/00003_password_reset_tokens.sql — žetonų saugykla, atkartojanti sessions:

token_hash TEXT NOT NULL UNIQUE,        -- maiša, niekada ne žetonas
user_id    UUID NOT NULL REFERENCES users(id) ON DELETE CASCADE,
expires_at TIMESTAMPTZ NOT NULL,
used_at    TIMESTAMPTZ                  -- NULL kol nepanaudotas → vienkartinis

used_at — vienkartinio vėliava: NULL reiškia šviežias, laiko žyma — panaudotas.

2. internal/db/queries/password_resets.sql — keturios užklausos: CreatePasswordReset, GetValidPasswordReset (ta, kuri užtikrina taisykles — used_at IS NULL AND expires_at > now()), MarkPasswordResetUsed ir InvalidateUserPasswordResets (sunaikinti visus vartotojo likusius).

3. internal/db/queries/users.sql (modify) — viena nauja užklausa, UpdateUserPassword. Grynas papildymas.

4. internal/db/queries/sessions.sql (modify) — viena nauja užklausa, DeleteSessionsForUser — „atjungti visus įrenginius" užklausa, kurią kvies užbaigtas atstatymas. Taip pat grynas papildymas.

5. internal/auth/token.go (naujas) — tas pats generatorius, kurį naudoja sesijos, dabar eksportuotas perpanaudojimui:

func GenerateToken() (raw, hash string, err error) {  // raw → nuoroda; hash → DB
	b := make([]byte, 32); rand.Read(b)
	raw = base64.RawURLEncoding.EncodeToString(b)
	return raw, HashToken(raw), nil
}
func HashToken(raw string) string { /* SHA-256, hex */ }

GenerateToken grąžina du dalykus: raw žetoną (keliauja į el. laiško nuorodą) ir jo hash (keliauja į duomenų bazę). Serveris niekada nesaugo raw žetono — tad, lygiai kaip sesijos ir slaptažodžiai, pavogta kopija neatskleidžia jokių veikiančių atstatymo nuorodų.