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

集成eBay OAuth API时无法用authorization_code换取access_token

解决eBay OAuth授权码交换access_token时的invalid_grant错误

问题描述

在C#应用中集成eBay沙箱OAuth API,使用authorization_code交换access_token时,持续收到以下错误:

{
    "error": "invalid_grant",
    "error_description": "the provided authorization grant code is invalid or was issued to another client"
}

当前实现流程:

  1. 生成授权URL引导用户登录授权,获取authorization_code:
string authCodeUrl = BuildAuthorizationUrl();
Console.WriteLine($"Please visit this URL to provide consent: {authCodeUrl}");
System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
{
    FileName = authCodeUrl,
    UseShellExecute = true
});
  1. 用户手动输入授权码后,调用以下方法交换令牌:
public async Task<string> GetAccessTokenAsync(string authorizationCode)
{
    string tokenUrl = "https://api.sandbox.ebay.com/identity/v1/oauth2/token";
    string clientId = "<Your Client ID>";
    string clientSecret = "<Your Client Secret>";
    string redirectUri = "http://localhost:8080/"; // Must match the redirect URI in eBay app settings

    using (var client = new HttpClient())
    {
        var authHeader = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{clientId}:{clientSecret}"));
        client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Basic", authHeader);

        var parameters = new Dictionary<string, string>
        {
            { "grant_type", "authorization_code" },
            { "code", authorizationCode },
            { "redirect_uri", redirectUri }
        };

        var content = new FormUrlEncodedContent(parameters);
        var response = await client.PostAsync(tokenUrl, content);

        string responseBody = await response.Content.ReadAsStringAsync();

        if (!response.IsSuccessStatusCode)
        {
            Console.WriteLine($"Error: {responseBody}");
            throw new Exception($"Error retrieving the access token. Response: {responseBody}");
        }

        var tokenResponse = JsonConvert.DeserializeObject<AccessTokenResponse>(responseBody);
        return tokenResponse.access_token;
    }
}

预期成功响应格式:

{
    "access_token": "v^1.1#i^1#p^3#r^1...XzMjRV4xMjg0",
    "expires_in": 7200,
    "refresh_token": "v^1.1#i^1#p^3#r^1...zYjRV4xMjg0",
    "refresh_token_expires_in": 47304000,
    "token_type": "User Access Token"
}

排查与解决步骤

  • 验证授权码有效性

    • 授权码仅能使用一次,若之前尝试过交换令牌,必须重新获取新的授权码。
    • 手动输入时易出现字符遗漏、多余空格或换行,建议直接复制粘贴授权码,避免手动输入错误。
  • 确保Client凭证与环境匹配

    • 沙箱环境与生产环境的Client ID/Secret完全独立,确认使用的是沙箱环境的凭证(因为令牌请求地址是沙箱的api.sandbox.ebay.com)。
    • 检查Client ID和Secret是否完整复制,无拼写错误或字符截断。
  • 严格匹配Redirect URI

    • 生成授权URL时的redirect_uri必须与令牌交换时的redirect_uri完全一致,包括末尾的斜杠、端口、大小写(例如你代码中用的http://localhost:8080/,授权URL里的参数也要完全相同)。
    • 同时要与eBay开发者平台中应用设置的Redirect URI完全匹配,任何细微差异都会导致错误。
  • 检查授权URL生成逻辑

    • 确认BuildAuthorizationUrl生成的URL包含正确参数:
      • client_id为沙箱Client ID
      • response_type必须是code
      • redirect_uri与后续交换时一致
      • scope符合应用申请的权限范围
    • 正确的沙箱授权URL示例:
      https://auth.sandbox.ebay.com/oauth2/authorize?client_id=YOUR_SANDBOX_CLIENT_ID&redirect_uri=http%3A%2F%2Flocalhost%3A8080%2F&response_type=code&scope=https%3A%2F%2Fapi.ebay.com%2Foauth%2Fapi_scope%2Fsell.inventory
      
  • 确认请求格式正确性

    • Basic Auth编码使用Encoding.ASCII是正确的,避免使用UTF-8编码导致凭证解析错误。
    • 表单参数grant_type必须为authorization_code,code参数值为用户提供的授权码,无额外修改。
  • 保持环境一致性

    • 授权URL必须使用沙箱的授权地址https://auth.sandbox.ebay.com,令牌请求使用沙箱的令牌地址,不能混用生产环境地址。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.16 02:05:21