当前位置:首页 > 文章列表 > 文章 > php教程 > PHP cURL 实现登录 CSRF Token 处理方法

PHP cURL 实现登录 CSRF Token 处理方法

2026-05-16 17:03:50 0浏览 收藏
本文深入解析了使用 PHP cURL 自动登录受 CSRF 保护网站时的关键痛点与实战解决方案,直击“CSRF token mismatch”错误根源——会话中断与 token 提交失配,并系统性地揭示了 Cookie 持久化失效、cURL 句柄未复用、POST 数据手动拼接导致编码错误等常见陷阱;通过复用同一 cURL 实例、正确配置 CURLOPT_COOKIEJAR/CURLOPT_COOKIEFILE、精准提取表单 name 属性并配合 http_build_query 安全构造请求体,辅以 User-Agent 模拟、重定向处理和时效性控制等细节优化,提供了一套稳定、可靠且合规的自动化登录实现路径,特别适合需要对接如 Bourse Direct 等强安全防护系统的开发者快速落地实践。

如何在 PHP cURL 中正确处理 CSRF Token 实现网站登录

本文详解使用 PHP cURL 登录含 CSRF 保护的网站时,如何通过保持会话、正确提取并提交 token 来避免“CSRF token mismatch”错误。核心在于复用同一 cURL 句柄、启用 Cookie 持久化,并规范构造 POST 数据。

本文详解使用 PHP cURL 登录含 CSRF 保护的网站时,如何通过保持会话、正确提取并提交 token 来避免“CSRF token mismatch”错误。核心在于复用同一 cURL 句柄、启用 Cookie 持久化,并规范构造 POST 数据。

在自动化登录受 CSRF(Cross-Site Request Forgery)保护的网站(如 Bourse Direct)时,常见误区是:虽成功提取了隐藏表单字段中的 token(如 <input type="hidden" id="bd_auth_login_type__token" name="bd_auth_login_type[_token]" value="yDVyvTXUhIJjnAj9mTfBO3OKgRpI0zLCUZY2BM_O1E8">),却因会话状态丢失或请求参数格式错误导致提交失败。

关键问题在于原代码中两个严重缺陷:

  1. 未启用 Cookie 存储与复用
    尽管设置了 CURLOPT_COOKIEJAR 和 CURLOPT_COOKIEFILE,但 'tmp' 文件不存在且未被写入;更严重的是,第二次请求前未重置 URL 和 POST 配置,也未确保 Cookie 被携带到登录接口。CSRF token 通常绑定于服务端 session,而 session 依赖 Cookie(如 PHPSESSID)。若 cookie 未持久化并随 POST 请求发出,服务器将视为新会话,生成新 token,导致校验失败。

  2. POST 数据构造不规范
    原始代码手动拼接 CURLOPT_POSTFIELDS 字符串,易引发 URL 编码错误(如特殊字符未转义)或键名不匹配(HTML 中 name="bd_auth_login_type[_token]",而非 token)。应使用 http_build_query() 确保键名精确、值安全编码。

✅ 正确实践如下:

  • 复用同一 cURL 句柄:避免新建连接导致上下文丢失;
  • 启用 Cookie 支持:设置 CURLOPT_COOKIEJAR(保存 cookie 到文件)和 CURLOPT_COOKIEFILE(读取 cookie,可设为同名文件或 /dev/null 临时使用);
  • 确保登录请求 URL 与表单 action 一致(通常为 /login 或 /,需检查 HTML 中
    );
  • 严格匹配表单字段 name 属性:从 DOM 提取 token 后,以 name 属性为准构造数据数组;
  • 使用 http_build_query() 序列化 POST 数据:保障编码合规性。

以下是优化后的完整示例(已验证可用):

<?php
$loginUrl = "https://www.boursedirect.fr/fr/login";

// 初始化 cURL 并获取登录页(触发 session + 获取 token)
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $loginUrl);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:100.0) Gecko/20100101 Firefox/100.0");
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookies.txt');  // 保存 cookie
curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookies.txt');  // 发送 cookie(复用)

// 可选:添加 headers 提升兼容性
curl_setopt($ch, CURLOPT_HTTPHEADER, [
    'Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language: en-US,en;q=0.5',
    'Upgrade-Insecure-Requests: 1'
]);

$html = curl_exec($ch);
if (curl_error($ch)) {
    die('cURL error: ' . curl_error($ch));
}

// 解析 HTML 提取 CSRF token
$dom = new DOMDocument();
libxml_use_internal_errors(true); // 忽略 HTML 解析警告
$dom->loadHTML($html);
libxml_clear_errors();

$tokenInput = $dom->getElementById("bd_auth_login_type__token");
if (!$tokenInput || !$tokenInput->hasAttribute('value')) {
    die('CSRF token not found in login form');
}
$csrfToken = $tokenInput->getAttribute('value');

// 构造登录数据(严格匹配表单 name 属性)
$loginData = [
    'bd_auth_login_type[login]'    => 'your_username',
    'bd_auth_login_type[password]' => 'your_password',
    'bd_auto_login_type[submit]'   => '', // 空值亦需提交
    'bd_auth_login_type[_token]'   => $csrfToken // 注意:name 是 "_token",非 "token"
];

// 执行 POST 登录请求(复用同一 $ch 句柄)
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($loginData));
curl_setopt($ch, CURLOPT_URL, $loginUrl); // 显式设置目标 URL

$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

if ($httpCode === 200 || $httpCode === 302) {
    echo "Login likely succeeded.\n";
    // 可进一步检查响应内容是否包含欢迎信息或跳转至仪表盘
} else {
    echo "Login failed. HTTP status: {$httpCode}\n";
    // 调试:echo $response;
}

curl_close($ch);
unlink('cookies.txt'); // 清理临时 cookie 文件(可选)
?>

⚠️ 重要注意事项

  • Cookie 文件路径必须可写:确保脚本有权限创建/写入 cookies.txt;
  • User-Agent 和 Headers 需模拟真实浏览器:部分站点会拦截无头请求;
  • 检查登录后重定向:成功登录常伴随 302 Found 跳转,可通过 CURLOPT_FOLLOWLOCATION 自动跟进,或检查 CURLINFO_REDIRECT_URL;
  • Token 时效性:CSRF token 通常有时效(如 30 分钟),务必在获取后立即提交;
  • 法律与合规性:仅对拥有合法授权的系统进行自动化操作,遵守网站 robots.txt 及服务条款。

掌握以上要点,即可稳定绕过 CSRF 防护完成自动化登录,为后续数据抓取或集成提供可靠基础。

文中关于的知识介绍,希望对你的学习有所帮助!若是受益匪浅,那就动动鼠标收藏这篇《PHP cURL 实现登录 CSRF Token 处理方法》文章吧,也可关注golang学习网公众号了解相关技术文章。

HTML animation-delay延迟设置方法HTML animation-delay延迟设置方法
上一篇
HTML animation-delay延迟设置方法
喜马拉雅免费会员领取方法及活动攻略
下一篇
喜马拉雅免费会员领取方法及活动攻略
查看更多
最新文章
资料下载
查看更多
课程推荐
  • 前端进阶之JavaScript设计模式
    前端进阶之JavaScript设计模式
    设计模式是开发人员在软件开发过程中面临一般问题时的解决方案,代表了最佳的实践。本课程的主打内容包括JS常见设计模式以及具体应用场景,打造一站式知识长龙服务,适合有JS基础的同学学习。
    543次学习
  • GO语言核心编程课程
    GO语言核心编程课程
    本课程采用真实案例,全面具体可落地,从理论到实践,一步一步将GO核心编程技术、编程思想、底层实现融会贯通,使学习者贴近时代脉搏,做IT互联网时代的弄潮儿。
    516次学习
  • 简单聊聊mysql8与网络通信
    简单聊聊mysql8与网络通信
    如有问题加微信:Le-studyg;在课程中,我们将首先介绍MySQL8的新特性,包括性能优化、安全增强、新数据类型等,帮助学生快速熟悉MySQL8的最新功能。接着,我们将深入解析MySQL的网络通信机制,包括协议、连接管理、数据传输等,让
    500次学习
  • JavaScript正则表达式基础与实战
    JavaScript正则表达式基础与实战
    在任何一门编程语言中,正则表达式,都是一项重要的知识,它提供了高效的字符串匹配与捕获机制,可以极大的简化程序设计。
    487次学习
  • 从零制作响应式网站—Grid布局
    从零制作响应式网站—Grid布局
    本系列教程将展示从零制作一个假想的网络科技公司官网,分为导航,轮播,关于我们,成功案例,服务流程,团队介绍,数据部分,公司动态,底部信息等内容区块。网站整体采用CSSGrid布局,支持响应式,有流畅过渡和展现动画。
    485次学习
查看更多
AI推荐
  • ChatExcel酷表:告别Excel难题,北大团队AI助手助您轻松处理数据
    ChatExcel酷表
    ChatExcel酷表是由北京大学团队打造的Excel聊天机器人,用自然语言操控表格,简化数据处理,告别繁琐操作,提升工作效率!适用于学生、上班族及政府人员。
    4541次使用
  • Any绘本:开源免费AI绘本创作工具深度解析
    Any绘本
    探索Any绘本(anypicturebook.com/zh),一款开源免费的AI绘本创作工具,基于Google Gemini与Flux AI模型,让您轻松创作个性化绘本。适用于家庭、教育、创作等多种场景,零门槛,高自由度,技术透明,本地可控。
    4904次使用
  • 可赞AI:AI驱动办公可视化智能工具,一键高效生成文档图表脑图
    可赞AI
    可赞AI,AI驱动的办公可视化智能工具,助您轻松实现文本与可视化元素高效转化。无论是智能文档生成、多格式文本解析,还是一键生成专业图表、脑图、知识卡片,可赞AI都能让信息处理更清晰高效。覆盖数据汇报、会议纪要、内容营销等全场景,大幅提升办公效率,降低专业门槛,是您提升工作效率的得力助手。
    4774次使用
  • 星月写作:AI网文创作神器,助力爆款小说速成
    星月写作
    星月写作是国内首款聚焦中文网络小说创作的AI辅助工具,解决网文作者从构思到变现的全流程痛点。AI扫榜、专属模板、全链路适配,助力新人快速上手,资深作者效率倍增。
    6653次使用
  • MagicLight.ai:叙事驱动AI动画视频创作平台 | 高效生成专业级故事动画
    MagicLight
    MagicLight.ai是全球首款叙事驱动型AI动画视频创作平台,专注于解决从故事想法到完整动画的全流程痛点。它通过自研AI模型,保障角色、风格、场景高度一致性,让零动画经验者也能高效产出专业级叙事内容。广泛适用于独立创作者、动画工作室、教育机构及企业营销,助您轻松实现创意落地与商业化。
    5136次使用
微信登录更方便
  • 密码登录
  • 注册账号
登录即同意 用户协议隐私政策
返回登录
  • 重置密码