Enhance Steam login flow by adding nonce validation and error handling in callback logic
All checks were successful
CI - Build and Push / Build and Push Docker Image (push) Successful in 50s

This commit is contained in:
2025-10-08 13:34:08 +08:00
parent 4ca8e1db57
commit 9cec502091
2 changed files with 39 additions and 3 deletions

View File

@@ -32,6 +32,39 @@ func (l *SteamLoginCallbackLogic) SteamLoginCallback(req *types.SteamLoginCallba
// Get the frontend callback URL from config
frontendCallbackURL := l.svcCtx.Config.Steam.FrontendCallbackURL
// Extract nonce from query parameter
nonce := r.URL.Query().Get("nonce")
if nonce == "" {
l.Logger.Errorf("Missing nonce in callback request")
redirectURL := fmt.Sprintf("%s?status=error&message=%s", frontendCallbackURL, url.QueryEscape("Invalid login session"))
http.Redirect(w, r, redirectURL, http.StatusFound)
return nil
}
// Validate nonce exists in Redis
nonceKey := nonceKeyPrefix + nonce
exists, err := l.svcCtx.Redis.Exists(nonceKey)
if err != nil {
l.Logger.Errorf("Failed to check nonce in Redis: %v", err)
redirectURL := fmt.Sprintf("%s?status=error&message=%s", frontendCallbackURL, url.QueryEscape("Session validation failed"))
http.Redirect(w, r, redirectURL, http.StatusFound)
return nil
}
if !exists {
l.Logger.Errorf("Invalid or expired nonce: %s", nonce)
redirectURL := fmt.Sprintf("%s?status=error&message=%s", frontendCallbackURL, url.QueryEscape("Login session expired or invalid"))
http.Redirect(w, r, redirectURL, http.StatusFound)
return nil
}
// Delete nonce from Redis to prevent replay attacks
_, err = l.svcCtx.Redis.Del(nonceKey)
if err != nil {
l.Logger.Errorf("Failed to delete nonce from Redis: %v", err)
// Continue anyway - nonce will expire naturally
}
// Convert the request to a map for validation
openidParams := map[string]string{
"openid.mode": req.OpenidMode,
@@ -57,7 +90,7 @@ func (l *SteamLoginCallbackLogic) SteamLoginCallback(req *types.SteamLoginCallba
}
if !isValid {
l.Logger.Infof("Invalid Steam OpenID response")
l.Logger.Errorf("Invalid Steam OpenID response")
// Redirect to frontend with failure status
redirectURL := fmt.Sprintf("%s?status=failed&message=%s", frontendCallbackURL, url.QueryEscape("Steam authentication failed"))
http.Redirect(w, r, redirectURL, http.StatusFound)
@@ -65,7 +98,7 @@ func (l *SteamLoginCallbackLogic) SteamLoginCallback(req *types.SteamLoginCallba
}
// Successful validation
l.Logger.Infof("Steam login successful for Steam ID: %s", steamID)
l.Logger.Infof("Steam login successful for Steam ID: %s (nonce: %s)", steamID, nonce)
// Redirect to frontend with success status and Steam ID
redirectURL := fmt.Sprintf("%s?status=success&steamId=%s", frontendCallbackURL, steamID)

View File

@@ -51,8 +51,11 @@ func (l *SteamLoginInitLogic) SteamLoginInit(req *types.SteamLoginInitReq, w htt
// Get the callback URL from config
callbackURL := l.svcCtx.Config.Steam.CallbackURL
// Append nonce to callback URL for validation later
callbackURLWithNonce := fmt.Sprintf("%s?nonce=%s", callbackURL, nonce)
// Build the Steam OpenID redirect URL
redirectURL := steamauth.GetRedirectURL(callbackURL)
redirectURL := steamauth.GetRedirectURL(callbackURLWithNonce)
l.Logger.Infof("Initiating Steam login with nonce: %s, callback URL: %s", nonce, callbackURL)