2026-06-16 10:10:21 +08:00
|
|
|
package app
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"net/http"
|
|
|
|
|
"time"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
func (a *App) issueSession(w http.ResponseWriter, r *http.Request, userID string) error {
|
|
|
|
|
token := randomToken()
|
|
|
|
|
sessionID := newID("ses")
|
2026-08-03 19:51:27 +08:00
|
|
|
expires := a.now().UTC().Add(time.Duration(a.config().SessionTTLHours) * time.Hour)
|
2026-06-16 10:10:21 +08:00
|
|
|
if _, err := a.db.ExecContext(r.Context(), `INSERT INTO sessions(id,user_id,token_hash,expires_at,created_at) VALUES(?,?,?,?,?)`,
|
|
|
|
|
sessionID, userID, hashToken(token), expires.Format(time.RFC3339Nano), a.now().UTC().Format(time.RFC3339Nano)); err != nil {
|
|
|
|
|
return err
|
|
|
|
|
}
|
|
|
|
|
http.SetCookie(w, &http.Cookie{
|
2026-08-03 19:51:27 +08:00
|
|
|
Name: a.config().CookieName,
|
2026-06-16 10:10:21 +08:00
|
|
|
Value: token,
|
|
|
|
|
Path: "/",
|
|
|
|
|
Expires: expires,
|
|
|
|
|
MaxAge: int(time.Until(expires).Seconds()),
|
|
|
|
|
HttpOnly: true,
|
|
|
|
|
SameSite: http.SameSiteLaxMode,
|
2026-08-03 19:51:27 +08:00
|
|
|
Secure: !a.config().AllowInsecureHTTP,
|
2026-06-16 10:10:21 +08:00
|
|
|
})
|
|
|
|
|
return nil
|
|
|
|
|
}
|