跨域转发提交数据并全程保持服务端处理的技术方案咨询
Hey there! Let's tackle this problem where you need to route user-submitted data to different backend servers entirely on the server side, without exposing those target URLs to clients. Since cross-domain issues block session usage and your initial curl followlocation attempt didn't work, here are three solid approaches to make this work:
1. Route Based on a Unique User Identifier in the Request
First, ensure the incoming request includes a unique user identifier (like a user ID, API key, or custom header) that your server can use to map to the correct target server. This avoids relying on sessions entirely.
Example PHP Implementation
<?php // Get incoming data (adjust based on your content type: form-data, JSON, etc.) $submittedData = $_POST; // Use json_decode(file_get_contents('php://input'), true) for JSON payloads // Retrieve user identifier (could come from a custom header, API key in form data, etc.) $userIdentifier = $_SERVER['HTTP_X_USER_ID'] ?? $submittedData['user_id'] ?? null; // Define your user-to-server routing map $serverMap = [ 'user1' => 'https://eastcoast.server1.com', 'user2' => 'https://westcoast.server2.com', // Add more user-server pairs here ]; // Validate identifier and fetch target server if (!isset($serverMap[$userIdentifier])) { http_response_code(400); echo "Invalid user identifier"; exit; } $targetServer = $serverMap[$userIdentifier]; // Combine submitted data with server-generated info $forwardData = array_merge( $submittedData, [ 'server_trace_id' => uniqid('route_', true), 'timestamp' => time(), 'source_origin' => 'data.mysite.com' ] ); // Set up curl for server-side forwarding $ch = curl_init($targetServer); curl_setopt($ch, CURLOPT_POST, true); // Use json_encode($forwardData) if target expects JSON instead of form data curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($forwardData)); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); // Only enable followlocation if you need to follow redirects from the target server // curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true); // Execute request and handle results $response = curl_exec($ch); if (curl_errno($ch)) { http_response_code(500); echo "Failed to process request: " . curl_error($ch); } else { // Return a generic success response to the client (hide target server details) echo "Data submitted successfully"; } curl_close($ch); ?>
Why Your Initial followlocation Might Have Failed
- The target server might be returning redirects that require authentication headers your curl request wasn't sending.
- You may have forgotten to set
CURLOPT_RETURNTRANSFER, which causes curl to output redirect responses directly instead of letting you handle them. - If the target uses HTTPS, ensure your server has valid SSL certificates (or disable verification temporarily for testing with
CURLOPT_SSL_VERIFYPEER => false).
2. Use JWT for Stateless User Authentication
If you need to authenticate users without sessions, JWT (JSON Web Tokens) is a great stateless alternative. Clients send a JWT in the Authorization header, your server decodes it to get user info, then routes accordingly.
Example JWT-Based Routing
<?php require 'vendor/autoload.php'; // Use the firebase/php-jwt package // Extract JWT from Authorization header $authHeader = $_SERVER['HTTP_AUTHORIZATION'] ?? null; if (!$authHeader || strpos($authHeader, 'Bearer ') !== 0) { http_response_code(401); echo "Unauthorized"; exit; } $jwt = substr($authHeader, 7); // Decode JWT with your secure secret key $secretKey = 'your_strong_secret_key_here'; try { $payload = Firebase\JWT\JWT::decode($jwt, $secretKey, ['HS256']); $userIdentifier = $payload->user_id; } catch (Exception $e) { http_response_code(401); echo "Invalid authentication token"; exit; } // Rest of the routing logic matches Approach 1: map user to target server and forward data ?>
3. Route Based on IP Geolocation
If you don't have a user identifier, you can use IP geolocation to route users to region-specific servers (e.g., east vs west coast). Use a server-side geolocation database or API to avoid exposing this logic to clients.
Example IP-Based Routing
<?php // Get user's IP address $userIp = $_SERVER['REMOTE_ADDR']; // Use a geolocation library (e.g., geoip2/geoip2) to fetch region data require 'vendor/autoload.php'; $reader = new GeoIp2\Database\Reader('/path/to/GeoLite2-City.mmdb'); try { $record = $reader->city($userIp); $regionCode = $record->mostSpecificSubdivision->isoCode; // e.g., 'NY' for East Coast, 'CA' for West Coast } catch (Exception $e) { http_response_code(500); echo "Failed to determine location"; exit; } // Map region codes to target servers $serverMap = [ 'NY' => 'https://eastcoast.server1.com', 'CA' => 'https://westcoast.server2.com', // Add more region-server pairs here ]; $targetServer = $serverMap[$regionCode] ?? 'https://fallback.server.com'; // Forward data as in Approach 1 ?>
Key Notes for All Approaches
- Client-Side Privacy: All routing logic runs on your
data.mysite.comserver—clients only ever interact with this URL, so target servers remain completely hidden. - Security: Always use HTTPS to encrypt data in transit. For sensitive information, add additional encryption before forwarding.
- Error Handling: Implement robust error handling for cases where the target server is down or returns errors—avoid exposing internal server details to clients.
内容的提问来源于stack exchange,提问作者MarkB

