You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Yii2配置Telegram Webhook返回302错误的解决求助

解决Yii2中Telegram Webhook返回302错误的配置问题

问题概述

将Telegram Webhook配置到Yii2项目的site/webhook路由后,Telegram返回302 Found错误,无法正常接收消息数据;若将Webhook指向根目录独立文件可获取数据,但无法执行数据库操作,需调整Yii2项目配置解决该问题。

当前配置

根目录.htaccess

Options +FollowSymLinks

IndexIgnore /
RewriteEngine on

RewriteCond %{REQUEST_URI} ^/admin
RewriteRule ^admin\/?(.*) /backend/web/$1

RewriteCond %{REQUEST_URI} !^/(frontend/web|backend/web|admin|site/webhook)
RewriteRule (.*) /frontend/web/$1 [L]

RewriteCond %{REQUEST_URI} ^/frontend/web
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /frontend/web/index.php [L]

RewriteCond %{REQUEST_URI} ^/backend/web
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /backend/web/index.php [L]

前端SiteController代码

public function actionSetWebhook()
{
    Yii::$app->telegram->setWebhook([
        'url' => Yii::$app->urlManager->createAbsoluteUrl(['site/webhook']),
    ]);

}
public function actionWebhook()
{
    $data = file_get_contents('php://input');
    $data = json_decode($data, true);
}

错误信息

Telegram返回结果

{"ok":true,"result":{"url":"https://домен/site/webhook","has_custom_certificate":false,"pending_update_count":35,"last_error_date":1680856667,"last_error_message":"Wrong response from the webhook: 302 Found","max_connections":40,"ip_address":"айпи"}}

Yii2应用日志

2023-04-07 11:37:47 [айпи][-][-][info][application] $_GET = [
    'r' => 'site/webhook'
]

$_POST = []

$_FILES = []

$_COOKIE = []

$_SERVER = [
    'REDIRECT_HTTPS' => 'on'
    'REDIRECT_downgrade-1_0' => ''
    'REDIRECT_suppress-error-charset' => ''
    'REDIRECT_STATUS' => '200'
    'HTTPS' => 'on'
    'downgrade-1_0' => ''
    'suppress-error-charset' => ''
    'HTTP_HOST' => 'домен'
    'HTTP_X_REAL_IP' => 'айпи'
    'HTTP_X_PROTOCOL' => 'HTTP/1.1'
    'HTTP_X_SERVER_IP' => 'айпи'
    'HTTP_X_FORWARDED_PROTOCOL' => 'https'
    'HTTP_X_FORWARDED_PROTO' => 'https'
    'HTTP_CONNECTION' => 'close'
    'CONTENT_LENGTH' => '444'
    'CONTENT_TYPE' => 'application/json'
    'HTTP_ACCEPT_ENCODING' => 'gzip, deflate'
    'PATH' => '/usr/bin:/bin:/usr/local/bin'
    'SERVER_SIGNATURE' => ''
    'SERVER_SOFTWARE' => 'Apache'
    'SERVER_NAME' => 'домен'
    'SERVER_ADDR' => 'айпи'
    'SERVER_PORT' => '80'
    'REMOTE_ADDR' => 'айпи'
    'DOCUMENT_ROOT' => '/home/users/o/аккаунт/domains/домен'
    'REQUEST_SCHEME' => 'http'
    'CONTEXT_PREFIX' => ''
    'CONTEXT_DOCUMENT_ROOT' => '/home/users/o/аккаунт/domains/домен'
    'SERVER_ADMIN' => 'info@jino.ru'
    'SCRIPT_FILENAME' => '/home/users/o/аккаунт/domains/домен/frontend/web/index.php'
    'REMOTE_PORT' => '36426'
    'REDIRECT_URL' => '/site/webhook'
    'REDIRECT_QUERY_STRING' => 'r=site/webhook'
    'GATEWAY_INTERFACE' => 'CGI/1.1'
    'SERVER_PROTOCOL' => 'HTTP/1.0'
    'REQUEST_METHOD' => 'POST'
    'QUERY_STRING' => 'r=site/webhook'
    'REQUEST_URI' => '/site/webhook'
    'SCRIPT_NAME' => '/frontend/web/index.php'
    'PHP_SELF' => '/frontend/web/index.php'
    'REQUEST_TIME_FLOAT' => 1680856667.8266
    'REQUEST_TIME' => 1680856667
]

解决方案

1. 调整.htaccess重写规则

修改根目录.htaccess,确保/site/webhook请求直接转发到Yii2前端入口文件:

Options +FollowSymLinks

IndexIgnore /
RewriteEngine on

# 处理admin路由到backend
RewriteCond %{REQUEST_URI} ^/admin
RewriteRule ^admin\/?(.*) /backend/web/$1 [L]

# 专门处理webhook路由,直接转发到frontend入口
RewriteRule ^site/webhook(/.*)?$ /frontend/web/index.php [L]

# 其他请求转发到frontend/web
RewriteCond %{REQUEST_URI} !^/(frontend/web|backend/web|admin)
RewriteRule (.*) /frontend/web/$1 [L]

# frontend的URL重写
RewriteCond %{REQUEST_URI} ^/frontend/web
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /frontend/web/index.php [L]

# backend的URL重写
RewriteCond %{REQUEST_URI} ^/backend/web
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /backend/web/index.php [L]

2. 关闭Webhook路由的CSRF验证

Telegram发送的是JSON格式POST请求,不携带CSRF Token,需在SiteController中针对webhook动作关闭CSRF验证:

public function beforeAction($action)
{
    if ($action->id === 'webhook') {
        $this->enableCsrfValidation = false;
    }
    return parent::beforeAction($action);
}

3. 确保Webhook动作返回200响应

Telegram要求Webhook必须返回200状态码,修改actionWebhook:

public function actionWebhook()
{
    $data = file_get_contents('php://input');
    $data = json_decode($data, true);
    
    // 在这里添加消息处理逻辑(如写入数据库等)
    
    // 返回符合要求的200响应
    Yii::$app->response->format = \yii\web\Response::FORMAT_RAW;
    Yii::$app->response->headers->set('Content-Type', 'text/plain');
    return 'ok';
}

4. 配置Yii2识别HTTPS请求

若服务器通过反向代理提供HTTPS,需在frontend/config/main.php的request组件中配置信任代理:

'components' => [
    'request' => [
        'trustedHosts' => ['домен'],
        'trustedProxies' => [
            '你的服务器反向代理IP', // 或Telegram的IP段
        ],
        'secureHeaders' => [
            \yii\web\Request::HEADER_X_FORWARDED_PROTO => 'https',
        ],
    ],
    // 其他组件配置...
]

内容的提问来源于stack exchange,提问作者Максим Егоров

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 15:27:00