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
All checks were successful
CI - Build and Push / Build and Push Docker Image (push) Successful in 50s
This commit is contained in:
@@ -32,6 +32,39 @@ func (l *SteamLoginCallbackLogic) SteamLoginCallback(req *types.SteamLoginCallba
|
|||||||
// Get the frontend callback URL from config
|
// Get the frontend callback URL from config
|
||||||
frontendCallbackURL := l.svcCtx.Config.Steam.FrontendCallbackURL
|
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
|
// Convert the request to a map for validation
|
||||||
openidParams := map[string]string{
|
openidParams := map[string]string{
|
||||||
"openid.mode": req.OpenidMode,
|
"openid.mode": req.OpenidMode,
|
||||||
@@ -57,7 +90,7 @@ func (l *SteamLoginCallbackLogic) SteamLoginCallback(req *types.SteamLoginCallba
|
|||||||
}
|
}
|
||||||
|
|
||||||
if !isValid {
|
if !isValid {
|
||||||
l.Logger.Infof("Invalid Steam OpenID response")
|
l.Logger.Errorf("Invalid Steam OpenID response")
|
||||||
// Redirect to frontend with failure status
|
// Redirect to frontend with failure status
|
||||||
redirectURL := fmt.Sprintf("%s?status=failed&message=%s", frontendCallbackURL, url.QueryEscape("Steam authentication failed"))
|
redirectURL := fmt.Sprintf("%s?status=failed&message=%s", frontendCallbackURL, url.QueryEscape("Steam authentication failed"))
|
||||||
http.Redirect(w, r, redirectURL, http.StatusFound)
|
http.Redirect(w, r, redirectURL, http.StatusFound)
|
||||||
@@ -65,7 +98,7 @@ func (l *SteamLoginCallbackLogic) SteamLoginCallback(req *types.SteamLoginCallba
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Successful validation
|
// 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
|
// Redirect to frontend with success status and Steam ID
|
||||||
redirectURL := fmt.Sprintf("%s?status=success&steamId=%s", frontendCallbackURL, steamID)
|
redirectURL := fmt.Sprintf("%s?status=success&steamId=%s", frontendCallbackURL, steamID)
|
||||||
|
|||||||
@@ -51,8 +51,11 @@ func (l *SteamLoginInitLogic) SteamLoginInit(req *types.SteamLoginInitReq, w htt
|
|||||||
// Get the callback URL from config
|
// Get the callback URL from config
|
||||||
callbackURL := l.svcCtx.Config.Steam.CallbackURL
|
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
|
// 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)
|
l.Logger.Infof("Initiating Steam login with nonce: %s, callback URL: %s", nonce, callbackURL)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user