在重定向期间切换协议
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
也可能存在问题的注释。以上是关于在重定向期间切换协议的主要内容,如果未能解决你的问题,请参考以下文章