Yii框架怎么做接口签名验证_Yii框架API接口安全认证Token方案【技巧】

酷磊君_6487

酷磊君_6487

2026-04-24

193人浏览

原创

Yii框架不提供接口签名验证功能,需自行实现;Bearer Token仅认证身份,无法防止请求重放或篡改,必须结合时间戳、nonce、参数排序与密钥摘要等机制进行签名校验,且应通过ActionFilter在beforeAction中前置执行。

yii框架怎么做接口签名验证_yii框架api接口安全认证token方案【技巧】

Yii 框架本身不提供接口签名验证(sign)功能,必须自己实现;直接套用 HttpBearerAuth 或 QueryParamAuth 只能做 token 认证,无法校验请求体、时间戳、nonce、签名字段是否被篡改。

为什么不能只靠 Bearer Token?

Bearer Token 解决的是“你是谁”,但不解决“这个请求是不是被中间人重放或篡改过”。比如攻击者截获一次合法请求,稍作修改(如把金额从 100 改成 1000)再原样重发,只要 token 还有效,服务端就会执行——除非你额外加签名机制。

签名验证的核心是:客户端和服务端用约定好的规则(参数排序 + 时间戳 + nonce + 密钥)生成摘要,服务端收到后复现一遍,比对结果是否一致。

  • 常见错误是只对 URL 参数签名,忽略 POST body(尤其是 JSON)
  • 没校验 timestamp 是否超时(建议 ≤ 5 分钟),导致重放攻击可行
  • 没检查 nonce 是否已存在 Redis(防重复提交),或用时间戳代替 nonce(不安全)
  • 密钥硬编码在代码里,或通过 HTTP 传密钥(绝对禁止)

怎么在 Yii2 中插入签名验证逻辑?

别改 authenticator 行为类,那是给 token 用的。签名验证属于「请求前置校验」,应放在 beforeAction() 或自定义 Filter 里,且必须在路由解析之后、action 执行之前运行。

推荐做法:写一个 SignatureFilter 类,继承 \yii\base\ActionFilter,在 beforeAction() 中提取并校验签名:

public function beforeAction($action)
{
    $request = \Yii::$app->request;
    $params = array_merge($request->get(), $request->getBodyParams());
    $timestamp = $params['timestamp'] ?? null;
    $nonce = $params['nonce'] ?? null;
    $sign = $params['sign'] ?? null;
<pre class="brush:php;toolbar:false;">if (!$timestamp || !$nonce || !$sign) {
    throw new \yii\web\BadRequestHttpException('Missing required sign params');
}

// 校验时间戳
if (abs(time() - (int)$timestamp) > 300) {
    throw new \yii\web\UnauthorizedHttpException('Timestamp expired');
}

// 校验 nonce 是否已用过(Redis key: sign:nonce:{nonce},TTL 300s)
$cacheKey = 'sign:nonce:' . $nonce;
if (\Yii::$app->cache->exists($cacheKey)) {
    throw new \yii\web\ForbiddenHttpException('Nonce reused');
}
\Yii::$app->cache->set($cacheKey, 1, 300);

// 拼接待签名字符串(按字典序排序 key,不含 sign 本身)
ksort($params);
unset($params['sign']);
$strToSign = http_build_query($params) . \Yii::$app->params['apiSecret'];

if ($sign !== hash_hmac('sha256', $strToSign, \Yii::$app->params['apiSecret'])) {
    throw new \yii\web\UnauthorizedHttpException('Invalid signature');
}

return true;

}

  • 注意:JSON 请求体需提前 decode 成数组,$request->getBodyParams() 默认只处理 application/x-www-form-urlencoded
  • apiSecret 必须存在 config/params.php 中,绝不能暴露在 URL 或日志里
  • 如果用 Nginx,确保 client_max_body_size 足够大,否则 JSON body 会被截断,签名必然失败

签名和 Bearer Token 能不能一起用?

可以,而且推荐:token 管身份,签名管防篡改和重放。两者是正交的,互不干扰。

Yii Framework 2.0.51
Yii Framework 2.0.51

Yii Framework 2.0.51 官方 Basic 应用模板,适合旧项目兼容、升级验证和开发测试。

下载

关键点在于执行顺序和作用域:

  • HttpBearerAuth 在 authenticator 行为中运行,负责设置 \Yii::$app->user->identity
  • SignatureFilter 应配置在 behaviors() 的 authenticator 之后(或独立注册),它不依赖用户登录态,甚至可在未登录时运行(比如开放注册接口)
  • 不要在 findIdentityByAccessToken() 里塞签名逻辑——那会污染认证流程,且无法覆盖匿名接口

配置示例:

public function behaviors()
{
    return [
        'authenticator' => [
            'class' => \yii\filters\auth\HttpBearerAuth::class,
        ],
        'signature' => [
            'class' => \app\filters\SignatureFilter::class,
        ],
    ];
}

容易被忽略的兼容性细节

签名验证看着简单,但线上最容易翻车的是环境和协议层问题:

  • Apache 下,$_SERVER['QUERY_STRING'] 和 parse_str() 对空值、+ 号、编码的处理和 Nginx 不一致,建议统一用 $request->get() + $request->getBodyParams()
  • cURL 测试时,如果用 -d '{"a":1}' 但没设 -H "Content-Type: application/json",Yii 默认不会解析 JSON body,getBodyParams() 返回空数组
  • 前端 JS 用 fetch 发 JSON 请求,body: JSON.stringify(...) 后必须手动加 headers: {'Content-Type': 'application/json'},否则签名字符串漏掉 body 内容
  • 移动端 SDK 如果自动添加 X-Requested-With 或其他 header,而你的签名规则没包含这些字段,就会校验失败——签名规则文档必须明确声明参与签名的字段范围

真正难的不是写几行 hash 代码,而是让所有客户端严格遵守同一套参数组装与编码规范,并在服务端稳定还原出来。一旦某端用了不同排序逻辑或 URL 编码方式,签名就永远对不上。

大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!

相关文章

PHP速学视频免费教程(入门到精通)
PHP速学视频免费教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

相关标签:

yii框架 yii

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
登录token无效
登录token无效

登录token无效解决方法:1、检查token的有效期限,如果token已经过期,需要重新获取一个新的token;2、检查token的签名,如果签名不正确,需要重新获取一个新的token;3、检查密钥的正确性,如果密钥不正确,需要重新获取一个新的token;4、使用HTTPS协议传输token,建议使用HTTPS协议进行传输 ;5、使用双因素认证,双因素认证可以提高账户的安全性。

2023.09.14

12986

6

登录token无效怎么办
登录token无效怎么办

登录token无效的解决办法有检查Token是否过期、检查Token是否正确、检查Token是否被篡改、检查Token是否与用户匹配、清除缓存或Cookie、检查网络连接和服务器状态、重新登录或请求新的Token、联系技术支持或开发人员等。本专题为大家提供token相关的文章、下载、课程内容,供大家免费下载体验。

2023.09.14

1565

5

token怎么获取
token怎么获取

获取token值的方法:1、小程序调用“wx.login()”获取 临时登录凭证code,并回传到开发者服务器;2、开发者服务器以code换取,用户唯一标识openid和会话密钥“session_key”。想了解更详细的内容,可以阅读本专题下面的文章。

2023.12.21

3517

3

token什么意思
token什么意思

token是一种用于表示用户权限、记录交易信息、支付虚拟货币的数字货币。可以用来在特定的网络上进行交易,用来购买或出售特定的虚拟货币,也可以用来支付特定的服务费用。想了解更多token什么意思的相关内容可以访问本专题下面的文章。

2024.03.01

5681

5

PHP Yii框架专题
PHP Yii框架专题

本专题专注于PHP主流框架Yii的应用,系统讲解MVC架构、路由机制、数据库操作、表单处理、安全验证与RESTful API 开发等核心内容。通过电商网站、后台管理系统与内容管理平台等实战项目,帮助学员快速掌握Yii框架的开发技巧与实战经验。

2025.09.04

2950

22

FrankenPHP集成Laravel详细教程
FrankenPHP集成Laravel详细教程

本专题提供FrankenPHP集成Laravel的详细配置指南,全面解析运行原理、开发环境搭建、Caddyfile配置、Octane工作模式、数据库连接、队列任务、定时任务和生产环境优化,解决部署过程中常见的报错与兼容性问题。

2026.10.08

40

20

LLVM自定义Pass怎么写
LLVM自定义Pass怎么写

本专题聚焦LLVM自定义Pass开发,整理Pass类结构、run()方法、PreservedAnalyses、CMake构建、插件注册、-load-pass-plugin加载和测试用例编写流程。

2026.09.30

140

10

LLVM RISC-V参数配置教程
LLVM RISC-V参数配置教程

本专题介绍LLVM对RISC-V基础ISA和扩展的支持方式,涵盖RV32、RV64、标准扩展、实验性扩展、厂商扩展、-menable-experimental-extensions和版本差异。

2026.09.30

140

14

LLVM IR中间表示入门指南
LLVM IR中间表示入门指南

本专题整理LLVM IR的核心概念,包括中间表示作用、模块结构、函数、基本块、SSA形式、类型系统和常见语法,帮助新手理解LLVM编译流程中的关键层。

2026.09.30

100

12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Yii2.0框架开发实战视频教程
Yii2.0框架开发实战视频教程

共22课时 | 9.3万人学习

Yii Framework 2.0 API 官方文档
Yii Framework 2.0 API 官方文档

共0课时 | 0人学习