无尘阁日记

无尘阁日记

Yii2系统对接实战:从0实现一个“连通测试接口”与安全错误封装(完整踩坑总结)
2026-03-13

我问:

curl --location --request POST 'http://43.226.237.162:48081/ess/api/oauth/zpy/test' \

--header 'Cookie: JSESSIONID=011198374FB12F4FBD594AB23CD197E6'


按这个给我们系统也写一个测试地址。也让他带Cookie,我是Yii2的,命名空间为namespace app\modules\api\modules\v1\controllers;也继承use app\modules\api\controllers\BaseAPIController;


给出必要注释。

AI答:

Yii2系统对接实战:从0实现一个“连通测试接口”与安全错误封装(完整踩坑总结)

在企业系统对接时,一个非常重要但经常被忽视的接口就是:连通测试接口(Connectivity Test API)

这个接口的作用并不是业务处理,而是用来解决三件非常实际的问题:


对方系统是否能访问到你的接口


请求头、Cookie、IP、方法等信息是否正确传递


如果系统发生错误,如何不暴露系统内部信息,而是返回一个安全、统一的JSON结构

下面这篇文章把整个实操过程完整整理出来,包括:

  • 接口设计

  • Yii2实现

  • beforeSend统一封装

  • psass接口异常安全处理

  • MethodNotAllowed 405异常处理

  • 实际踩过的坑

所有关键细节都会保留。

一、为什么要做“连通测试接口”

在系统对接初期,双方经常会遇到这些问题:

  • 对方系统访问接口报错

  • 请求方法不匹配

  • Cookie没带

  • Header丢失

  • IP获取不到

  • 系统异常把堆栈暴露出去

所以通常都会设计一个 Test / Ping接口

例如:

POST /api/v1/psass/test

作用只有一个:

验证系统是否联通。

二、设计统一返回结构

为了便于对接系统解析,接口必须返回统一结构。

推荐结构:

{
  "code": 0,
  "message": "connect success",
  "data": {
    "server_time": "...",
    "client_ip": "...",
    "method": "...",
    "jsessionid": "...",
    "headers": {...}
  }
}

字段说明

字段含义
code业务状态码
message提示信息
data具体数据
server_time服务器时间
client_ip客户端IP
method请求方法
jsessionidCookie信息
headers请求头

三、Yii2实现连通测试接口

Controller代码如下。

路径示例

app/modules/api/modules/v1/controllers/TestController.php

代码示例

namespace app\modules\api\modules\v1\controllers;

use Yii;
use app\modules\api\controllers\BaseAPIController;

class TestController extends BaseAPIController
{

    public function actionPsassTest()
    {
        $request = Yii::$app->request;

        $cookies = $request->cookies;
        $headers = $request->headers->toArray();

        $ip = $request->userIP;
        $jsessionId = $cookies->getValue('JSESSIONID', null);

        return [
            'code' => 0,
            'message' => 'connect success',
            'data' => [
                'server_time' => date('Y-m-d H:i:s'),
                'client_ip' => $ip,
                'method' => $request->method,
                'jsessionid' => $jsessionId,
                'headers' => $headers
            ]
        ];
    }

}

四、curl测试示例

对方系统可以这样测试。

curl --location --request POST 'http://your-domain/api/v1/psass/test' \
--header 'Cookie: JSESSIONID=011198374FB12F4FBD594AB23CD197E6'

如果返回:

connect success

说明:

  • 网络通

  • 接口通

  • Cookie正常

  • Header正常

五、企业级需求:异常不能暴露系统信息

真实环境中,如果接口出现错误,例如:

405 Method Not Allowed
500 Internal Server Error
SQL异常
PHP Fatal error

Yii2默认会返回:

[
 'name' => 'Method Not Allowed',
 'message' => 'Method Not Allowed...',
 'status' => 405,
 'type' => 'yii\web\MethodNotAllowedHttpException'
]

这会暴露:

  • 框架类型

  • 系统异常

  • 技术栈

在对外接口中这是 不安全的

所以必须统一封装。

六、使用 beforeSend 统一封装响应

Yii2提供一个重要事件:

Response::EVENT_BEFORE_SEND

作用:

在响应发送给客户端之前进行统一处理。

例如:

bootstrap.php

绑定事件:

Yii::$app->response->on(
    \yii\web\Response::EVENT_BEFORE_SEND,
    function ($event) {
        checkNuoming();
    }
);

七、psass接口异常统一封装

我们只针对包含 psass 的接口做特殊处理。

实现代码:

private static function checkNuoming()
{
    $route = Yii::$app->request->pathInfo;

    Yii::error($route, '判断错误部分');
    Yii::error(Yii::$app->response->statusCode);

    if (strpos($route, 'psass') !== false && Yii::$app->response->statusCode !== 200) {

        Yii::error(Yii::$app->response->data, '检测到psass接口异常,封装错误信息返回');

        $request = Yii::$app->request;
        $cookies = $request->cookies;
        $headers = $request->headers->toArray();
        $ip = $request->userIP;

        $jsessionId = $cookies->getValue('JSESSIONID', null);

        $msg = 'Unknown error';

        if (is_array(Yii::$app->response->data) && isset(Yii::$app->response->data['message'])) {
            $msg = Yii::$app->response->data['message'];
        }

        Yii::$app->response->format = \yii\web\Response::FORMAT_JSON;

        Yii::$app->response->statusCode = 200;

        Yii::$app->response->data = [
            'code' => -1,
            'message' => $msg,
            'data' => [
                'server_time' => date('Y-m-d H:i:s'),
                'client_ip' => $ip,
                'method' => $request->method,
                'jsessionid' => $jsessionId,
                'headers' => $headers
            ]
        ];
    }
}

八、关键踩坑总结

整个实现过程中有几个非常容易踩的坑。

坑一

beforeSend return 不会自动成为响应

错误写法:

return [...]

这是普通函数返回值。

不会自动变成:

response->data

正确做法:

Yii::$app->response->data = [...]

坑二

405错误结构来自 Yii errorHandler

如果接口只允许 POST

而你发 GET

Yii会自动抛:

MethodNotAllowedHttpException

返回结构:

Method Not Allowed

必须在 beforeSend 中重新封装。

坑三

response->statusCode 需要重新设置

如果仍然保持:

405
500

很多网关或SDK会直接认为请求失败。

推荐统一返回:

HTTP 200
业务code = -1

坑四

response->data 未必一定是数组

异常情况下可能是:

  • string

  • null

  • object

必须判断:

is_array(...)

否则会报错。

九、最终效果

正常接口

{
 "code":0,
 "message":"connect success",
 "data":{...}
}

系统异常

{
 "code":-1,
 "message":"Method Not Allowed",
 "data":{...}
}

不会再暴露:

yii\web\MethodNotAllowedHttpException
stack trace
file path

十、连通测试接口的真正价值

一个好的 连通测试接口 可以解决:


系统网络问题


认证问题


Cookie传递问题


接口权限问题


异常安全问题

在企业系统对接中,这是一个 非常重要的基础设施接口

很多大型系统(OAuth / SSO / API Gateway)都会提供类似接口:

/ping
/health
/test
/connect

总结

实现一个可靠的系统对接测试接口,需要解决四个核心问题:


接口连通性


请求信息验证


统一返回结构


异常安全封装

通过:

  • Yii2 Controller

  • Response beforeSend

  • psass路由检测

  • 统一JSON结构

就可以实现一个 安全、稳定、企业级的对接测试接口体系