package handler import ( "net/http" "server/internal/config" "server/internal/model/request" "server/internal/pkg/errs" "server/internal/pkg/httputil" "server/internal/service" "time" ) type AuthHandler struct { authService *service.AuthService cfg *config.Config } func NewAuthHandler(authService *service.AuthService, cfg *config.Config) *AuthHandler { return &AuthHandler{authService: authService, cfg: cfg} } func (h *AuthHandler) clearRefreshTokenCookie(w http.ResponseWriter) { http.SetCookie(w, &http.Cookie{ Name: h.cfg.JWTConfig.CookieName, Value: "", Path: "/", HttpOnly: true, Secure: true, SameSite: http.SameSiteNoneMode, MaxAge: -1, Expires: time.Unix(0, 0), }) } func (h *AuthHandler) Login(w http.ResponseWriter, r *http.Request) { var req request.LoginRequest if err := httputil.BindJson(r, &req); err != nil { httputil.Fail(w, errs.ErrInvalidCredentials) return } res, err := h.authService.Login(r.Context(), req) if err != nil { httputil.Fail(w, err) return } http.SetCookie(w, &http.Cookie{ Name: h.cfg.JWTConfig.CookieName, Value: res.RefreshToken, Path: "/", HttpOnly: true, Secure: true, SameSite: http.SameSiteNoneMode, Expires: res.RefreshTokenExp, }) httputil.Ok(w, map[string]any{ "access_token": res.AccessToken, "access_token_exp": res.AccessTokenExp, }) } func (h *AuthHandler) Logout(w http.ResponseWriter, r *http.Request) { cookie, err := r.Cookie(h.cfg.JWTConfig.CookieName) if err == nil { _ = h.authService.Logout(r.Context(), cookie.Value) } h.clearRefreshTokenCookie(w) httputil.Ok(w) } func (h *AuthHandler) RefreshToken(w http.ResponseWriter, r *http.Request) { cookie, err := r.Cookie(h.cfg.JWTConfig.CookieName) if err != nil { h.clearRefreshTokenCookie(w) httputil.Fail(w, errs.ErrInvalidRefreshToken) return } res, err := h.authService.RefreshToken(r.Context(), cookie.Value) if err != nil { // 用户被禁用 调用logout _ = h.authService.Logout(r.Context(), cookie.Value) h.clearRefreshTokenCookie(w) httputil.Fail(w, err) return } httputil.Ok(w, map[string]any{ "access_token": res.AccessToken, "access_token_exp": res.AccessTokenExp, }) }