百度站长工具「加站 → 验证 → 文件同步」里那个 baidutoken.php,我是这么活下来的适用场景:百度搜索资源平台(ziyuan.baidu.com)加站流程第三步「验证网站」→ 选文件验证,要往站点根目录放一个百度给的验证文件,放好了百度才认这个站。代码落点:baidutoken.php(服务器端的「投递口」)+ baidu_flow.py 的 step3_v
详细介绍
百度站长工具「加站 → 验证 → 文件同步」里那个 baidutoken.php,我是这么活下来的
适用场景:百度搜索资源平台(ziyuan.baidu.com)加站流程第三步「验证网站」→ 选文件验证,
要往站点根目录放一个百度给的验证文件,放好了百度才认这个站。
代码落点:baidutoken.php(服务器端的「投递口」)+baidu_flow.py的step3_verify()(客户端的「投递员」)
一句话结论:**这个 php 只要老实干「写文件 / 删文件」两件事就够了。
真正把人坑死的不是代码,是顺序(先确认验证成功再删)、命名(协议 / www / 大小写都算不同站)
和「假 200」(文件根本不存在,站点也回你 200)。**
0. 先吐槽:为什么非得有这么个文件
我一开始的脑回路是:百度要验证文件,那我用 FTP / 宝塔面板手动传一下不就行了?
传第一次可以,第二次想死。整个流程是「加站 → 验证 → 拿 TOKEN → 推链接 → TOKEN 用完了删站 → 再加新站」,
这条链是要跑几千遍的。手传?做梦。
于是思路变成:既然软件跑在本地,服务器在远端,那就找个「远端能写文件」的口子。
最省事的口子就是——在网站根目录扔一个 php,本地 POST 过去,让它自己把文件写出来。
这就是 baidutoken.php。它不是什么高深玩意,就是个只认识两个字段的文件接收器:
文件名:百度给啥就写啥,别自己拼,带后缀
正文内容:百度给的内容原样落盘,一个字节都别改
再配一个「删文件」的动作,用完自己擦干净,收工。
1. 它在整个流程里站哪个位置
一句人话:它是「百度验证文件」从百度 → 你的站点服务器的搬运通道;顺便兼了个「用完删掉」的保洁。
百度(ziyuan.baidu.com) 本地软件(跑在你这台机器) 你的站点服务器
│ 第三步页面给个下载链接 │ │
│ ──── /site/verifyfile?id=<站点ID> ──────▶ │(带 Cookie 请求,慢,别急) │
│ ◀──── 返回文件名 + 验证内容 ──────────────│ │
│ │ ── POST 文件名 + 正文内容 ──────▶ │ baidutoken.php 落盘
│ │ ◀── {"code":0,"file":...} ───── │
│ │ ── GET https://域名/<文件名> ───▶ │ 期望 200 且内容一致
│ ◀── POST /site/verify (id + type=file) ──│ │
│ ──── {"status":0,...} 验证通过 ─────────▶│ │
│ │ ── action=delete 删文件 ───────▶ │ baidutoken.php 删掉
│ 接着去 linksubmit 页面拿 API TOKEN │ │
注意两个细节,后面坑清单里还会骂:
下载接口是「延时返回」的——
/site/verifyfile?id=xxx其实是百度在服务端现场生成这个文件,
所以它挂几秒甚至十几秒才吐数据是完全正常的,别当成超时然后疯狂重试。
验证通过之后才删文件——顺序反了,站点在百度那边会一直挂「未验证」。
2. 对外契约(软件侧就是这么调它的)
| 项目 | 内容 |
|---|---|
| 接口地址 | https://{用户域名}/baidutoken.php(域名带不带 www、http 还是 https,是不同站点) |
| 请求方式 | POST(application/x-www-form-urlencoded),GET 也留着方便自测 |
| 写入字段 | 文件名、正文内容(就是中文字段名,别改成 file/content,除非你两边同时改) |
| 删除字段 | action=delete + 文件名 |
| 连通自测 | action=ping —— 一个请求确认「够不够得着 + 目录能不能写」 |
| 建议安全项 | key=...,和本地 config.json 里的值对上才放行 |
| 成功返回 | 建议 JSON:{"code":0,"msg":"ok","file":"...","size":123} |
配套的软件侧动作(baidu_flow.py):
step3_verify():抓下载链接 → 落盘 → POST 投递 → GET 校验 → 点「完成验证」→ 删文件
完成验证走的是
POST /site/verify,bodyid=<站点ID>&type=file,
返回 {"status":0,"isMainSite":false,"isFirstTime":true} —— 只有 status==0 才算真成功,
拿到别的值就把文件留着别删,然后 dump 现场(截图 + HTML)慢慢查。
删站是另一套逻辑(站点列表页),必须在「目标站点那一行」里找删除按钮,
我干过一次全局找按钮的事,差点把别人站点删了,后背发凉。
3. 完整成功时序(照这个顺序排就不会错)
打开第三步「验证网站」,选文件验证方式
带 Cookie 请求
/site/verifyfile?id=<站点ID>,耐心等,拿到验证文件(文件名 + 正文)
POST 到
https://{域名}/baidutoken.php:文件名+正文内容
服务端回
code:0
GET
https://{域名}/{文件名}?t=<随机数>(带随机数绕缓存),要求HTTP 200
响应正文和刚投递的内容逐字节一致
回百度页面点「完成验证」→
POST /site/verify→ 必须{"status":0}
确认
status==0之后,再 POSTaction=delete删掉验证文件
去
https://ziyuan.baidu.com/linksubmit/index?site=<带协议的域名>抓 API 提交地址
(形如 http://data.zz.baidu.com/urls?site=<域名>&token=<TOKEN>)
推链接,直到当天剩余条数为 0 → 删站 → 回到第 1 步加新站
4. 参考实现:能直接把文件投递进去的 baidutoken.php
如果你服务器上那份丢了、或者要给别人复用,照这个写就行。
放到网站根目录,和要验证的站点同一个域名下。
<?php
/**
* baidutoken.php —— 百度站点验证文件的「投递口」
* 只干两件事:写文件、删文件。
* 字段:文件名 / 正文内容 / action / key
*/
header('Content-Type: application/json; charset=utf-8');
header('Cache-Control: no-store');
$SECRET = 'CHANGE_ME_一串随机字符串'; // 必须和软件 config.json 里的 verify.key 一致
$baseDir = __DIR__; // 默认:php 所在目录(= 网站根目录)
$logFile = __DIR__ . '/baidutoken.log';
function out($code, $msg, $extra = array()) {
echo json_encode(array_merge(array('code' => $code, 'msg' => $msg), $extra), JSON_UNESCAPED_UNICODE);
exit;
}
function logline($logFile, $text) {
if (@filesize($logFile) > 5 * 1024 * 1024) { @rename($logFile, $logFile . '.1'); }
@file_put_contents($logFile, date('Y-m-d H:i:s') . ' ' . $text . "\n", FILE_APPEND | LOCK_EX);
}
$in = array_merge($_GET, $_POST);
$action = isset($in['action']) ? strtolower(trim($in['action'])) : 'save';
$key = isset($in['key']) ? trim($in['key']) : '';
if ($SECRET !== '' && $key !== $SECRET) {
logline($logFile, 'bad key from ' . $_SERVER['REMOTE_ADDR']);
out(403, 'key 不对');
}
if ($action === 'ping') { // 连通性自测:够不够得着、目录能不能写
out(is_writable($baseDir) ? 0 : 1, 'ping', array('dir' => $baseDir, 'writable' => is_writable($baseDir)));
}
/* 文件名过滤:只留一层文件名,挡掉路径穿越和稀奇古怪的字符 */
function safe_name($name) {
$name = trim((string)$name);
$name = str_replace('\\', '/', $name);
$name = basename($name); // 干掉 ../ 之类
if ($name === '' || $name === '.' || $name === '..') return '';
if (strpos($name, "\0") !== false) return '';
if (!preg_match('/^[A-Za-z0-9._-]{1,120}$/', $name)) return ''; // 中文名在 Linux 上会变乱码
if (substr($name, 0, 1) === '.') return ''; // 不放隐藏文件
return $name;
}
$name = isset($in['文件名']) ? $in['文件名'] : (isset($in['filename']) ? $in['filename'] : '');
$body = isset($in['正文内容']) ? $in['正文内容'] : (isset($in['content']) ? $in['content'] : '');
$name = safe_name($name);
if ($name === '') { logline($logFile, 'bad filename'); out(400, '文件名不合法'); }
$path = $baseDir . DIRECTORY_SEPARATOR . $name;
if ($action === 'delete') {
if (is_file($path) && @unlink($path)) {
logline($logFile, 'delete ok ' . $name);
out(0, 'deleted', array('file' => $name));
}
logline($logFile, 'delete fail ' . $name);
out(1, '删除失败或文件不存在', array('file' => $name));
}
if ($action !== 'save') { out(400, '不认识的动作:' . $action); }
/* 原子写:先写临时文件再 rename,免得百度正好读到半截内容 */
$body = (string)$body;
if (strncmp($body, "\xEF\xBB\xBF", 3) === 0) { $body = substr($body, 3); } // 去掉 BOM!否则百度校验不过
$tmp = $path . '.tmp' . getmypid();
if (@file_put_contents($tmp, $body, LOCK_EX) === false) {
logline($logFile, 'write fail ' . $name);
out(1, '写文件失败,检查目录权限');
}
if (!@rename($tmp, $path)) { @unlink($tmp); out(1, '改名失败'); }
@chmod($path, 0644);
logline($logFile, 'save ok ' . $name . ' ' . strlen($body) . 'B ' . $_SERVER['REMOTE_ADDR']);
out(0, 'ok', array('file' => $name, 'size' => strlen($body)));
---
## 5. 坑清单(我一条一条踩过来的)
1. **「假 200」是最阴的坑。** 站点开了伪静态 / 自定义 404 页,随便一个不存在的文件也回 200。
你一看 200 就点「完成验证」,百度那边一对内容发现不对 → 白验证。
**必须比对响应正文**,不能只看状态码。
2. **协议 / www / 端口 / 大小写都算不同站点。** `http://a.com`、`https://a.com`、`https://www.a.com`
在百度眼里是三个站,TOKEN 不通用。我们真踩过:TOKEN 接口把域名写死成 `https://`,
站点却是 `http://`,直接 `Bad Request / site is wrong`。
3. **删文件删早了。** 必须等 `/site/verify` 返回 `status==0` 再删,否则站点一直挂「未验证」,
而且你还得重新走一遍第三步。
4. **删早了 → 重来;删错了 → 更大的事。** 删站按钮一定要限定在「目标站点那一行」里找。
5. **php 目录不可写。** 宝塔 / 容器 / 只读挂载都会中招,一定要先 `action=ping` 探一下。
6. **BOM 和多余换行。** 编辑器偷偷加 BOM、末尾自动加回车,百度对不上内容。落盘要按原字节写,
BOM 直接在服务端剥掉(参考实现里有)。
7. **别自己拼文件名。** 百度给的名字长这样:`baidu_verify_code-xxxxxxxx.html`(也可能给 `.txt`),
**原样用**。带中文 / 带空格的名字在 Linux 上会因为编码变成乱码文件名,百度自然也找不到。
8. **CDN / 反代缓存。** 刚写完 GET 到的是旧内容。校验 URL 加随机参数,或者 `Cache-Control: no-store`。
9. **下载接口慢是正常的。** `/site/verifyfile?id=xxx` 是现场生成,慢几秒到十几秒都正常,
别当超时然后重试成灾(重试多了还容易触发风控)。
10. **用完记得删。** 验证文件留着就是垃圾文件,而且暴露了「能写文件」的入口。
11. **入口安全别偷懒。** 这个 php 能写文件,不加 key 就是个上传漏洞。
我第一版没加,现在回想起来后背发凉。key + 文件名白名单 + 只允许一层文件名,缺一不可。
12. **别信 POST 的返回,要 GET 复检。** 返回 `code:0` 只代表「写完了」,
不代表「百度能读到、内容还对」。
13. **`/site/add` 报 403 + `server: bfe` 空响应 = 账号级临时风控。**
这时候第二步根本不会出现,别怀疑你的领域选择器。
实测证据:连页面自己发的请求都被拦。解法:**重新登录百度资源平台重新导出 `cookies.txt`**(最有效)
/ 换网络(手机热点)/ 配代理 / 退避重试(15 → 30 → 60 → 120 秒,最多 12 次)。
14. **跨域不用管。** 本地软件 POST 到站点,是「服务器到服务器」,不涉及浏览器同源策略,
别为这个去折腾 CORS。
---
## 6. 上线前自检 8 条
1. `?action=ping&key=xxx` 返回 `code:0`,且 `writable` 为真
2. 投一个测试文件,浏览器直接访问 `/{文件名}`,内容**逐字节一致**
3. 故意访问一个不存在的文件,确认站点**不会**回 200(防「假 200」)
4. `http://` 和 `https://` 两个域名各放一次(如果两个都是有效站点)
5. `www` 和非 `www` 分清,别把文件写到 A 站、验证 B 站
6. key 不对时返回 403(确认 key 真的生效了)
7. 文件名里塞 `../etc/passwd` 会被拒(确认过滤生效)
8. 走一遍完整链路:投递 → GET 校验 → 完成验证 `status==0` → 删除
---
## 7. 复用速查(几条 curl 就能测完)
bash
1. 够不够得着、能不能写
curl -s "https://你的域名/baidutoken.php?action=ping&key=你的KEY"
2. 投递(字段名就是中文;嫌编码麻烦可以用 filename / content 别名)
curl -s -X POST "https://你的域名/baidutoken.php" \
-d "key=你的KEY" \
-d "filename=baidu_verify_code-abcd1234.html" \
--data-urlencode "content=abcd1234token"
3. 自检(带随机数绕缓存;重点看正文,别被假 200 骗了)
curl -s -i "https://你的域名/baidu_verify_code-abcd1234.html?t=$RANDOM"
4. 删除(确认验证成功之后再执行)
curl -s -X POST "https://你的域名/baidutoken.php" \
-d "action=delete&key=你的KEY" \
-d "filename=baidu_verify_code-abcd1234.html"
```
8. 最后
这个 php 本身简单到不好意思单独写一篇文档。真正值得记下来的是这四句:
**原样搬运(字段名、文件名、正文一个都别改)+ 写完必复检(比内容,不看状态码)+
验证通过才删(status==0)+ 入口必须上锁(key + 文件名白名单)。**
把顺序排对,这个环节基本就不会再回来看第二眼了。
内容版权声明
内容链接:https://www.diezanrpa.com/jinengjiqiao/1408.html
内容标题:百度站长工具「加站 → 验证 → 文件同步」里那个 baidutoken.php,我是这么活下来的
当前文章由【谍赞AI助手】自主写作文案,内容版权归当前平台所有,用户可自由转载!
本文最后更新发布于【2026-10-11】,某些文章具有时效性,若有错误或已失效,请联系客服
争议处理:针对本文内容若有异义,亦可直接与【法律顾问:易兴俊,律师联系电话:13825799821】直接联系沟通

