跨域名重定向后如何获取原URL的GET参数及请求路径
可行性说明
直接通过HTTP请求的原生属性(比如你提到的:path)获取原跳转URL的GET参数不可行。因为3xx跳转后,目标域名(domainB)收到的是全新的请求,请求路径、参数都是针对domainB的,和原domainA的请求信息无关。浏览器自带的Referer头可能会包含原URL,但它不可靠(可能被浏览器禁用、截断参数或因跨协议跳转隐藏),所以必须通过主动传递的方式实现需求。
由于你拥有两个域名的代码修改权限,完全可以通过以下方案实现目标:
通用跳转场景实现方法
1. 跳转时主动传递原URL参数
在domainA的跳转代码中,将当前完整URL(含GET参数)编码后作为参数传给domainB:
// domainA的跳转代码 $fullOriginalUrl = "https://domainA.com" . $_SERVER['REQUEST_URI']; header("Location: https://domainB.com?from_url=" . urlencode($fullOriginalUrl)); exit;
在domainB中,直接读取并解码参数即可得到原URL:
// domainB的接收代码 $originalUrl = urldecode($_GET['from_url'] ?? ''); // 可直接跳转回原URL if ($originalUrl) { header("Location: " . $originalUrl); exit; }
2. 利用Session存储原URL
如果两个域名共享会话(比如同主域名的子域名,或通过Redis等共享存储实现跨域Session),可以在domainA跳转前将原URL存入Session:
// domainA的跳转代码 $_SESSION['original_redirect_url'] = "https://domainA.com" . $_SERVER['REQUEST_URI']; header("Location: https://domainB.com"); exit;
在domainB中读取Session即可获取原URL:
// domainB的接收代码 $originalUrl = $_SESSION['original_redirect_url'] ?? '';
注意:跨顶级域名的Session共享需要额外配置,比如设置Cookie的
domain为父域名,或使用分布式存储(Redis/Memcached)统一存储Session数据。
适配你的Mollie OAuth场景
你当前的OAuth跳转代码仅传递了域名,无法获取原URL的参数。结合OAuth流程的安全要求,推荐用Session存储原URL,具体修改如下:
步骤1:跳转授权页时存储原URL
修改domainA侧的OAuth跳转代码,在生成授权URL后,将原完整URL存入Session:
$this->provider = new \Mollie\OAuth2\Client\Provider\Mollie([ 'clientId' => 'XXXXXXX', 'clientSecret' => 'XXXXX', 'redirectUri' => 'https://example.com/oauth', ]); if (!isset($_GET['code'])) { $authorizationUrl = $provider->getAuthorizationUrl([ 'approval_prompt' => 'auto', 'scope' => [ \Mollie\OAuth2\Client\Provider\Mollie::SCOPE_PAYMENTS_READ, \Mollie\OAuth2\Client\Provider\Mollie::SCOPE_PAYMENTS_WRITE, \Mollie\OAuth2\Client\Provider\Mollie::SCOPE_REFUNDS_READ, \Mollie\OAuth2\Client\Provider\Mollie::SCOPE_REFUNDS_WRITE, \Mollie\OAuth2\Client\Provider\Mollie::SCOPE_PROFILES_READ, \Mollie\OAuth2\Client\Provider\Mollie::SCOPE_PROFILES_WRITE, \Mollie\OAuth2\Client\Provider\Mollie::SCOPE_ONBOARDING_READ, \Mollie\OAuth2\Client\Provider\Mollie::SCOPE_ORGANIZATIONS_READ, \Mollie\OAuth2\Client\Provider\Mollie::SCOPE_ORGANIZATIONS_WRITE ], ]); // 存储OAuth state和原URL到Session $_SESSION['oauth2state'] = $provider->getState(); $_SESSION['oauth_original_url'] = "https://" . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']; // 跳转至授权页面(无需额外拼接return参数) header('Location: ' . $authorizationUrl); exit; }
步骤2:授权回调时读取原URL
在你的redirectUri页面(https://example.com/oauth),验证OAuth state通过后,即可从Session取出原URL并使用:
// 假设这部分是redirectUri页面的代码 session_start(); if (isset($_GET['code']) && isset($_SESSION['oauth2state']) && $_GET['state'] === $_SESSION['oauth2state']) { // 验证state通过,获取原URL $originalUrl = $_SESSION['oauth_original_url'] ?? ''; // 跳转回原URL(实现类似window.history.back()的效果) if ($originalUrl) { header("Location: " . $originalUrl); exit; } // 后续的OAuth token获取、业务逻辑处理... $token = $provider->getAccessToken('authorization_code', [ 'code' => $_GET['code'] ]); // ... } else { // state验证失败,处理错误 unset($_SESSION['oauth2state']); exit('Invalid state'); }
为什么不用直接拼接参数到授权URL?因为Mollie的授权服务器不会将自定义参数(比如你之前加的
return)传递回回调地址,而Session存储是OAuth流程中安全可靠的方式——只有通过state验证的合法会话才能取出原URL。
内容的提问来源于stack exchange,提问作者I try so hard but I cry harder

