在重定向期间切换协议

Posted

技术标签:

【中文标题】在重定向期间切换协议【英文标题】:Protocol being switched during redirects 【发布时间】:2022-01-21 11:34:13 【问题描述】:

在我的 Cakephp 3.10 应用程序中,重定向改变了协议并破坏了应用程序。这正在部署到 Azure 中的应用服务 (PHP 7.4)。

我没有在本地的另一个 LAMP 堆栈(RHEL、Apache 2.4、PHP 7.3、https 配置)上看到这个。

例如,退出应用程序。

public function logout()

    $this->getRequest()->getSession()->write('isAdmin',false);
    $this->Flash->success(__('You are now logged out.'));
    return $this->redirect($this->Auth->logout());

在检查流量期间(通过 Edge 的 > Inspect > Network),这是我看到的(注意响应标头位置从 https 更改为 http):

一般

Request URL: https://my.domain.com/users/logout
Request Method: GET
Status Code: 302 Found
Remote Address: my.ip.here:443
Referrer Policy: strict-origin-when-cross-origin

响应标头

Cache-Control: no-store, no-cache, must-revalidate
Content-Length: 0
Content-Type: text/html; charset=UTF-8
Date: Sun, 19 Dec 2021 13:08:05 GMT
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Location: http://my.domain.com/
Pragma: no-cache
Server: Apache
Set-Cookie: CAKEPHP=deleted; expires=Thu, 01-Jan-1970 00:00:01 GMT; Max-Age=0; path=/; HttpOnly
Set-Cookie: CAKEPHP=c2be7c7d45c9418b06356bd95796ff8f; path=/; HttpOnly
X-Powered-By: PHP/7.4.24

请求标头

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.9
Accept-Encoding: gzip, deflate, br
Accept-Language: en-US,en;q=0.9
Connection: keep-alive
Cookie: csrfToken=09206701259fb54445122132512cf0e8f00cf2ac2f2cf42a34a49cd221b9e797c36d919696daad8d2fc77a0373e417e5e59a89a0cacc9c408ebeede1fc0b4446; CAKEPHP=c6ebd1412956de948b4857c4a0791f04
DNT: 1
Host: my.domain.com
Referer: https://my.domain.com/
sec-ch-ua: " Not A;Brand";v="99", "Chromium";v="96", "Microsoft Edge";v="96"
sec-ch-ua-mobile: ?0
sec-ch-ua-platform: "Windows"
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/96.0.4664.110 Safari/537.36 Edg/96.0.1054.62

【问题讨论】:

【参考方案1】:

像许多负载平衡器the Azure ones also like to terminate SSL 一样,到达 PHP 的请求将是未加密的,这使得 CakePHP 应用程序默认使用 env('HTTPS') 查找失败来构建完整的基本 URL。

/*
 * Set the full base URL.
 * This URL is used as the base of all absolute links.
 *
 * If you define fullBaseUrl in your config file you can remove this.
 */
if (!Configure::read('App.fullBaseUrl')) 
    $s = null;
    if (env('HTTPS')) 
        $s = 's';
    

    $httpHost = env('HTTP_HOST');
    if (isset($httpHost)) 
        Configure::write('App.fullBaseUrl', 'http' . $s . '://' . $httpHost);
    
    unset($httpHost, $s);

https://github.com/cakephp/app/blob/3.10.1/config/bootstrap.php#L131-L148

链接的 Azure 文档建议改为检查 HTTP_X_FORWARDED_PROTO 标头,该标头由负载均衡器填充,但您需要考虑到根据应用程序运行的环境,此标头也可能已设置由客户提供,所以我一般不建议使用它。

我建议对协议进行硬编码,或者更好的是,手动设置完整的完整基本 URL(至少在过去 HTTP_HOST 也是一个问题,因为一些服务器接受了从客户端发送的自定义值),例如:

Configure::write('App.fullBaseUrl', 'https://' . $httpHost);

或在您的config/app.php(或config/app_local.php)中设置App.fullBaseUrl

【讨论】:

我选择在 app_local.php 中设置它。我通过 SSH 在服务器上确认它在那里。但是,它仍然会访问 http。奇怪。 @TechFanDan 文件存在是一回事,实际使用的文件是另一回事。你必须做更多的挖掘来确定配置是否真的被设置(正确)。 我去看看。到目前为止,其中的其他配置正在被使用(即数据库凭据等)。也许我错过了一些东西,因为我只是将它附加到 app_local.php 文件中。 想通了! app_local.php 中的设置缺少前缀 App。似乎现在可以工作了!谢谢! @TechFanDan 我已经更新了我的答案,以更清楚地表明该选项嵌套在 App 中。还添加了关于HTTP_POST 也可能存在问题的注释。

以上是关于在重定向期间切换协议的主要内容,如果未能解决你的问题,请参考以下文章

laravel 4.2在重定向时重新生成会话

Passport.JS 卡在重定向

.htaccess 重定向而不更改地址栏

Nginx在重定向时复制查询字符串

谷歌开发者工具“网络”标签在重定向后清除

Symfony功能测试在重定向后断言