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

Roblox Web API认证失败求助:Token验证失败及跨端点调用异常

解决Roblox Web API跨端点CSRF Token失效问题

核心问题分析

Roblox的CSRF Token与请求域名强绑定——从auth.roblox.com获取的Token仅能用于该域名下的接口,调用其他子域名(如privatemessages.roblox.com)的API时,必须针对目标域名重新获取对应Token。此外你的原有代码存在关键错误:创建HttpClientHandler后未关联到HttpClient实例,导致Cookie容器和请求会话完全脱节。

修正后的完整代码

static async Task Main(string[] args)
{
    // 替换为你的有效.ROBLOSECURITY Cookie
    string robloxSecurityCookie = "YOUR_VALID_ROBLOSECURITY_COOKIE";
    
    // 针对私信接口域名获取专属CSRF Token
    string privateMessagesCsrf = await GetCsrfTokenForDomain("https://privatemessages.roblox.com/", robloxSecurityCookie);
    
    // 执行发送私信请求
    await SendPrivateMessage(privateMessagesCsrf, robloxSecurityCookie);
}

static async Task<string> GetCsrfTokenForDomain(string domainBaseUrl, string robloxSecurityCookie)
{
    using (var handler = new HttpClientHandler { CookieContainer = new CookieContainer() })
    using (var client = new HttpClient(handler))
    {
        // 将.ROBLOSECURITY Cookie注入目标域名的Cookie容器
        Uri domainUri = new Uri(domainBaseUrl);
        handler.CookieContainer.Add(domainUri, new Cookie(".ROBLOSECURITY", robloxSecurityCookie));
        
        // 发送HEAD请求触发CSRF Token返回(比POST更轻量)
        var response = await client.HeadAsync(domainBaseUrl);
        
        if (response.Headers.TryGetValues("x-csrf-token", out var values))
        {
            return values.FirstOrDefault();
        }
        
        throw new Exception($"Failed to retrieve CSRF token for domain: {domainBaseUrl}");
    }
}

static async Task SendPrivateMessage(string csrfToken, string robloxSecurityCookie)
{
    string apiUrl = "https://privatemessages.roblox.com/v1/messages/send";
    
    using (var handler = new HttpClientHandler { CookieContainer = new CookieContainer() })
    using (var client = new HttpClient(handler))
    {
        // 关联Cookie容器,确保会话一致
        Uri domainUri = new Uri(apiUrl);
        handler.CookieContainer.Add(domainUri, new Cookie(".ROBLOSECURITY", robloxSecurityCookie));
        
        // 注入专属CSRF Token到请求头
        client.DefaultRequestHeaders.Add("X-CSRF-TOKEN", csrfToken);
        
        // 构造私信请求参数(移除冗余的userId参数)
        var postData = new FormUrlEncodedContent(new[]
        {
            new KeyValuePair<string, string>("recipientId", "2222602108"),
            new KeyValuePair<string, string>("subject", "hey"),
            new KeyValuePair<string, string>("body", "thank you for adding me as a friend"),
            new KeyValuePair<string, string>("replyMessageId", "0"),
            new KeyValuePair<string, string>("includePreviousMessage", "false")
        });
        
        var response = await client.PostAsync(apiUrl, postData);
        
        if (response.IsSuccessStatusCode)
        {
            string responseContent = await response.Content.ReadAsStringAsync();
            Console.WriteLine("私信发送成功!响应内容:");
            Console.WriteLine(responseContent);
        }
        else
        {
            Console.WriteLine($"错误状态码:{response.StatusCode}");
            string errorContent = await response.Content.ReadAsStringAsync();
            Console.WriteLine("错误详情:");
            Console.WriteLine(errorContent);
        }
    }
}

关键修正点

  • 按域名生成CSRF Token:每个Roblox子域名的API需要单独获取对应Token,通过HEAD请求触发返回(比POST更高效)。
  • 正确关联HttpClientHandler:创建HttpClient时必须传入配置好CookieContainer的handler,确保Cookie随请求携带。
  • 清理冗余参数:私信接口无需userId参数,移除后避免请求校验报错。
  • 会话一致性保障:每个域名的请求使用独立的会话容器,确保Token与Cookie的绑定关系正确。

额外注意事项

  • 禁止跨域名复用CSRF Token,Roblox会严格验证Token生成域名与请求域名的一致性。
  • 确保.ROBLOSECURITY Cookie未过期,若账号开启二次验证,需额外处理验证流程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.23 21:05:58