You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C++ libcurl请求LeetCode GraphQL接口遇CSRF验证403错误

LeetCode GraphQL接口CSRF验证失败403问题修复

你的代码存在5个直接触发CSRF校验失败的核心问题,逐一修复即可正常请求:

核心错误点

  • POST请求载荷格式错误:LeetCode的GraphQL接口要求POST Body必须是包含query字段的合法JSON结构,你直接将GraphQL查询字符串作为请求体发送,不符合接口要求,会直接被安全规则拦截。
  • CSRF传参缺失:LeetCode的CSRF校验规则要求,除了Cookie中携带csrftoken,还必须在请求头中显式传递x-csrftoken字段,值与Cookie中的csrftoken完全一致,你仅在Cookie中传入token、未加对应请求头,必然触发验证失败。
  • CSRF Cookie获取逻辑错误:直接向/graphql端点发GET请求无法拿到合法的CSRF Cookie,必须先访问LeetCode公开页面(如题目列表页、首页),服务端才会下发和会话绑定的有效csrftoken。
  • 会话Cookie丢失:POST请求阶段你手动构造Cookie仅传入csrftoken,丢弃了GET阶段拿到的其他关联会话Cookie,服务端无法将token和当前请求会话绑定,验证无法通过。
  • 请求头格式错误:你写的User-Agent头中间存在硬换行,属于非法HTTP头格式,会导致服务端识别请求异常。

修复步骤

  1. 调整请求流程
    • 第一步发送GET请求到https://leetcode.com/problemset/all/,统一开启libcurl的自动Cookie管理(CURLOPT_COOKIEJAR和CURLOPT_COOKIEFILE指向同一个本地Cookie文件),不要手动拼接Cookie字符串,让libcurl自动维护所有会话Cookie。
    • GET请求完成后,从本地Cookie文件中解析出csrftoken字段的值。
    • 第二步发送POST请求到https://leetcode.com/graphql,复用同一个Cookie文件配置,libcurl会自动携带所有关联会话Cookie,不需要手动构造Cookie头。
  2. 修正POST请求配置
    • 将GraphQL查询语句包装为合法JSON格式,结构为{"query": "你的GraphQL查询内容"},注意转义特殊字符。
    • 在POST请求的头列表中新增x-csrftoken: 你解析到的csrftoken值头,同时补充Origin: https://leetcode.com头模拟浏览器请求。
    • 删除User-Agent头中的硬换行,保证所有HTTP头为单行合法格式。
    • 不管GET还是POST请求,都统一挂载通用请求头,不要仅在POST分支设置HTTP头。
  3. 资源回收补充:请求结束后主动释放curl_slist头列表、关闭打开的文件句柄,避免内存泄漏。

修正后的核心参考代码

void request(bool isGet = true, std::string csrf = "") {
    // 将GraphQL查询包装为合法JSON结构,使用原始字符串避免转义问题
    static std::string query = R"({
        "query": "query allQuestionsRaw{ allQuestions: allQuestionsRaw { title titleSlug translatedTitle questionId questionFrontendId status difficulty isPaidOnly categoryTitle __typename } }"
    })";

    curl_slist* hdrsl = NULL;
    hdrsl = curl_slist_append(hdrsl, "Content-Type: application/json");
    // 修复User-Agent换行问题
    hdrsl = curl_slist_append(hdrsl, "User-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/103.0.0.0 Safari/537.36");
    hdrsl = curl_slist_append(hdrsl, "Accept: */*");
    hdrsl = curl_slist_append(hdrsl, "Host: leetcode.com");
    hdrsl = curl_slist_append(hdrsl, "Origin: https://leetcode.com");
    // POST请求额外添加x-csrftoken头
    if (!isGet && !csrf.empty()) {
        std::string csrfHeader = "x-csrftoken: " + csrf;
        hdrsl = curl_slist_append(hdrsl, csrfHeader.c_str());
    }

    CURL* curl = curl_easy_init();
    FILE* fd = fopen("tasks.json", "w");
    
    // GET阶段请求题目列表页拿Cookie,POST阶段请求GraphQL接口
    if (isGet) {
        curl_easy_setopt(curl, CURLOPT_URL, "https://leetcode.com/problemset/all/");
    } else {
        curl_easy_setopt(curl, CURLOPT_URL, "https://leetcode.com/graphql");
    }
    
    curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
    // 所有请求统一挂载请求头
    curl_easy_setopt(curl, CURLOPT_HTTPHEADER, hdrsl);
    curl_easy_setopt(curl, CURLOPT_REFERER, "https://leetcode.com/problemset/all/?page=2");
    curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
    curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);
    // 统一配置Cookie自动管理,GET/POST共用同一个Cookie文件维护会话
    curl_easy_setopt(curl, CURLOPT_COOKIEJAR, "leetcode_cookie.txt");
    curl_easy_setopt(curl, CURLOPT_COOKIEFILE, "leetcode_cookie.txt");

    if (!isGet) {
        curl_easy_setopt(curl, CURLOPT_POST, 1L);
        curl_easy_setopt(curl, CURLOPT_POSTFIELDS, query.c_str());
    }

    curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, NULL);
    curl_easy_setopt(curl, CURLOPT_WRITEDATA, fd);
    curl_easy_perform(curl);

    // 主动释放资源
    curl_slist_free_all(hdrsl);
    curl_easy_cleanup(curl);
    fclose(fd);
}

如果按上述配置修改后仍遇到拦截,可以先在浏览器中正常访问LeetCode通过人机验证,再将浏览器生成的有效Cookie导出到代码使用的leetcode_cookie.txt文件中再发起请求。

内容的提问来源于stack exchange,提问作者WelcomeToMyTutorial

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 10:09:46