RESTful接口必须强制HTTPS以保护Bearer Token;Apache用.htaccess、IIS用web.config配置跳转,Yii层需兜底校验;注意CDN场景检查X-Forwarded-Proto,避免Mixed Content与HATEOAS链接错误。

RESTful 接口必须走 HTTPS,否则 Authorization 头里的 Bearer Token 极易被中间人截获;而 Yii 本身不自动强制跳转,得靠 Web 服务器或框架层干预——光配 urlManager 或改 baseUrl 没用,请求根本到不了 PHP 层。
Apache 下用 .htaccess 强制跳转 HTTPS(最常用)
Yii 应用通常部署在 Apache,直接在 web/ 目录下放 .htaccess 最可靠。注意不是项目根目录,而是 Web 入口所在目录(如 frontend/web 或 backend/web)。
常见错误是把规则写在错的层级,或没开启 mod_rewrite。正确写法:
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://%{HTTP_HOST}%{REQUEST_URI} [L,R=301]
- 必须确保 Apache 启用了
rewrite_module,否则规则完全不生效 -
RewriteCond %{HTTPS} off比检查端口更稳妥,兼容反向代理场景(如 Nginx + Apache 组合) - 别加
RewriteBase /—— Yii 的urlManager已处理路径前缀,重复会导致重定向循环 - RESTful 接口若被前端 AJAX 调用,301 会触发 CORS 预检失败;生产环境建议用
R=302临时跳转,调试期再切 301
IIS10 下用 web.config 强制跳转(Windows 环境)
宝塔或手动配 IIS 时,web.config 必须放在 Web 根目录(即 web/),且规则要放在 内部最前面,否则被其他规则拦截。
关键点是条件判断和动作分离,不能只写 就完事:
<rule name="Redirect to HTTPS" stopprocessing="true"><match url="(.*)"></match><conditions logicalgrouping="MatchAll"><add input="{HTTPS}" pattern="^OFF$"></add></conditions><action type="Redirect" url="https://{HTTP_HOST}{REQUEST_URI}" redirecttype="Permanent"></action></rule>
-
logicalGrouping="MatchAll"是必须的,否则条件无效 - IIS 管理器里该站点的 SSL 设置中,“要求 SSL”一定不能勾选,否则 HTTP 请求直接 403,根本进不了重写模块
- 如果用了 CDN 或负载均衡,
{HTTPS}可能永远是OFF;此时应检查{HTTP_X_FORWARDED_PROTO},改成
Yii 框架层补充校验(防绕过)
Web 服务器配置可能被绕过(比如本地开发时关了 HTTPS,或测试用 HTTP 直连 PHP-FPM)。可以在 Yii 入口或 BaseController 中加一层防御:
在 web/index.php 顶部加:
if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'on') {
header('Location: https://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);
exit;
}
- 比在控制器里做更早、更彻底,避免路由解析、中间件执行等开销
- 注意不要在 console 应用里执行这段——
$_SERVER['HTTPS']在 CLI 下不存在,会触发 Notice - RESTful 接口返回 JSON,但这个跳转是 302+HTML,前端 fetch 会报
TypeError: Failed to fetch;所以仅用于兜底,主逻辑仍靠 Web 服务器
RESTful 接口启用 HTTPS 后的常见坑
跳转配完不代表万事大吉。很多问题出在客户端调用或 Yii 自身行为上:
- 前端 JS 用
fetch('/api/v1/user')发请求:如果页面是 HTTPS,但 API 地址写成http://协议,浏览器直接拒绝(Mixed Content) -
UrlManager::createAbsoluteUrl()生成的链接仍是 HTTP:需在配置中显式设'hostInfo' => 'https://example.com',否则 REST 客户端收到的 HATEOAS 链接不可用 - Yii 日志组件写入文件时,若
runtime/目录权限不对,HTTPS 跳转后日志报错被静默吞掉,排查时发现“什么都没记录” - API 返回 302 跳转时,
Accept: application/json头还在,但响应体变成 HTML;这不是 Yii 的问题,是 Web 服务器跳转逻辑本身决定的——所以 REST 接口不该依赖跳转传参,参数必须走 query 或 body











