重定向期间切换的协议

Protocol being switched during redirects

在我的 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 的 > 检查 > 网络),这是我看到的(通知响应 Header 位置从 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

回复Header秒

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

请求Headers

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

与许多负载平衡器一样,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 header,它由负载均衡器填充,但您需要考虑到这一点,具体取决于应用程序运行的环境,这个header也可能是客户端设置的,所以我一般不推荐使用它。

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

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

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