refactor(auth): enhance error handling in OIDC login and callback handlers with user-friendly pages

This commit is contained in:
yusing
2025-12-22 10:35:07 +08:00
parent b248303487
commit 601864a3e9

View File

@@ -251,7 +251,7 @@ func (auth *OIDCProvider) LoginHandler(w http.ResponseWriter, r *http.Request) {
} }
if !rateLimit.Allow() { if !rateLimit.Allow() {
http.Error(w, "auth rate limit exceeded", http.StatusTooManyRequests) WriteBlockPage(w, http.StatusTooManyRequests, "auth rate limit exceeded", "Try again", OIDCAuthInitPath)
return return
} }
@@ -318,34 +318,39 @@ func (auth *OIDCProvider) PostAuthCallbackHandler(w http.ResponseWriter, r *http
// verify state // verify state
state, err := r.Cookie(auth.getAppScopedCookieName(CookieOauthState)) state, err := r.Cookie(auth.getAppScopedCookieName(CookieOauthState))
if err != nil { if err != nil {
http.Error(w, "missing state cookie", http.StatusBadRequest) auth.clearCookie(w, r)
WriteBlockPage(w, http.StatusBadRequest, "missing state cookie", "Back to Login", OIDCAuthInitPath)
return return
} }
if r.URL.Query().Get("state") != state.Value { if r.URL.Query().Get("state") != state.Value {
http.Error(w, "invalid oauth state", http.StatusBadRequest) auth.clearCookie(w, r)
WriteBlockPage(w, http.StatusBadRequest, "invalid oauth state", "Back to Login", OIDCAuthInitPath)
return return
} }
code := r.URL.Query().Get("code") code := r.URL.Query().Get("code")
oauth2Token, err := auth.oauthConfig.Exchange(r.Context(), code, optRedirectPostAuth(r)) oauth2Token, err := auth.oauthConfig.Exchange(r.Context(), code, optRedirectPostAuth(r))
if err != nil { if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError) auth.clearCookie(w, r)
httputils.LogError(r).Msg(fmt.Sprintf("failed to exchange token: %v", err)) WriteBlockPage(w, http.StatusInternalServerError, "failed to exchange token", "Try again", OIDCAuthInitPath)
httputils.LogError(r).Msgf("failed to exchange token: %v", err)
return return
} }
idTokenJWT, idToken, err := auth.getIDToken(r.Context(), oauth2Token) idTokenJWT, idToken, err := auth.getIDToken(r.Context(), oauth2Token)
if err != nil { if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError) auth.clearCookie(w, r)
httputils.LogError(r).Msg(fmt.Sprintf("failed to get ID token: %v", err)) WriteBlockPage(w, http.StatusInternalServerError, "failed to get ID token", "Try again", OIDCAuthInitPath)
httputils.LogError(r).Msgf("failed to get ID token: %v", err)
return return
} }
if oauth2Token.RefreshToken != "" { if oauth2Token.RefreshToken != "" {
claims, err := parseClaims(idToken) claims, err := parseClaims(idToken)
if err != nil { if err != nil {
http.Error(w, "Internal Server Error", http.StatusInternalServerError) auth.clearCookie(w, r)
httputils.LogError(r).Msg(fmt.Sprintf("failed to parse claims: %v", err)) WriteBlockPage(w, http.StatusInternalServerError, "failed to parse claims", "Try again", OIDCAuthInitPath)
httputils.LogError(r).Msgf("failed to parse claims: %v", err)
return return
} }
session := newSession(claims.Username, claims.Groups) session := newSession(claims.Username, claims.Groups)