使用curl从Cloudflare站点下载文件时CSRF token报错如何解决?
问题排查与修复方案
你脚本存在的核心问题
- CSRF Token提取方式不可靠:用
awk固定取第8个双引号分隔的内容,页面结构稍有变动就会提取到错误的Token,你当前返回的400错误大概率是提交的CSRF Token和Cookie中绑定的不匹配导致的 - 提交格式错误:你用
-F参数提交表单,会默认发送multipart/form-data格式的请求,Factorio的登录接口只接受标准的application/x-www-form-urlencoded格式的表单提交 - Cookie使用逻辑错误:
- 没有先清空历史遗留的Cookie文件,旧的session会干扰新的请求校验
- 最后下载文件的请求没有携带登录成功后的Cookie,即使登录成功也拿不到下载权限
- 冗余参数:
-X POST不需要加,用-d参数提交表单时curl会自动识别为POST请求,同时加X-CSRF-Token头属于多余操作,表单里带csrf_token参数就足够了
修正后的脚本
#!/bin/sh LOGIN="你的用户名" PASSWD="你的密码" VERSION=`curl -s "https://api.github.com/repos/wube/factorio-data/tags" | jq -r '.[0].name'` ARCHIVE="factorio_alpha_x64_${VERSION}.tar.xz" COOKIE_FILE="/tmp/factorio_cookie.txt" # 先清空旧Cookie rm -f $COOKIE_FILE # 请求登录页,同时存Cookie和提取CSRF Token,用更稳定的正则提取 CSRF=$(curl -s -c $COOKIE_FILE https://www.factorio.com/login | grep -oP 'name="csrf_token" value="\K[^"]+') # 提交登录请求,用urlencoded格式提交 curl -s -c $COOKIE_FILE -b $COOKIE_FILE \ -d "csrf_token=${CSRF}" \ -d "username_or_email=${LOGIN}" \ -d "password=${PASSWD}" \ https://www.factorio.com/login > /dev/null # 携带Cookie下载文件,加-L跟随重定向,因为下载链接会跳转到CDN地址 curl -L -b $COOKIE_FILE https://www.factorio.com/get-download/${VERSION}/alpha/linux64 -o ${ARCHIVE} # 清理临时Cookie rm -f $COOKIE_FILE
额外注意事项
- 不要把明文账号密码写在脚本里,可以改为从环境变量读取,比如执行脚本时用
FACTORIO_USER=你的账号 FACTORIO_PASS=你的密码 ./downloader.sh的方式传入 - 如果还是触发Cloudflare拦截,可以给所有curl请求加
-A参数模拟浏览器UA,比如-A "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36"
内容的提问来源于stack exchange,提问作者Cybervitexus
相关产品推荐
相关产品推荐

