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

使用C#实现API自动化测试:Bearer Token获取求助

API自动化测试Bearer Token鉴权问题排查与修复

你的代码存在几个关键问题导致鉴权失败,以下是问题点和修复后的完整实现:

问题点梳理

  • 未定义ApiUrl常量:Test_ApiAuthentication方法中调用MakeAuthenticatedRequestAsync时使用了ApiUrl,但类中未声明该常量,编译会报错
  • Token请求参数传递方式错误:使用AddParameter默认会把参数放到QueryString,而client_credentials模式的Token请求要求参数放在请求体中
  • 错误排查信息不足:仅输出状态码和描述,未打印响应内容,难以定位Token获取失败的具体原因
  • RestClient重复创建:每次请求都新建RestClient,不符合最佳实践,可复用实例提升性能

修复后的完整代码

using System;
using System.Threading.Tasks;
using Newtonsoft.Json.Linq;
using NUnit.Framework;
using RestSharp;
using FluentAssertions;

namespace AutoTest1.TestFixtures
{
    [TestFixture]
    public class ApiTests
    {
        // 补充缺失的API地址常量
        private const string ApiUrl = "https://testapi.com/your-target-endpoint";
        private const string TokenUrl = "https://testapi.com/token";
        private const string ClientId = "123456789";
        private const string ClientSecret = "1000222";
        
        // 复用RestClient实例
        private RestClient _restClient;

        [SetUp]
        public void Setup()
        {
            _restClient = new RestClient();
        }

        [Test]
        public async Task Test_ApiAuthentication()
        {
            var token = await GetBearerTokenAsync();
            token.Should().NotBeNullOrEmpty("Token should be retrieved successfully");

            var responseContent = await MakeAuthenticatedRequestAsync(token);
            responseContent.Should().NotBeNull("Response content should be received");
            Console.WriteLine($"API Response: {responseContent}");
        }

        [Test]
        public async Task TokenRetrieval()
        {
            var token = await GetBearerTokenAsync();
            token.Should().NotBeNullOrEmpty("Token should be retrieved successfully");
        }

        private async Task<string> GetBearerTokenAsync()
        {
            var request = new RestRequest(TokenUrl, Method.Post);
            
            // 明确指定参数放入请求体,符合x-www-form-urlencoded格式要求
            request.AddParameter("grant_type", "client_credentials", ParameterType.RequestBody);
            request.AddParameter("client_id", ClientId, ParameterType.RequestBody);
            request.AddParameter("client_secret", ClientSecret, ParameterType.RequestBody);
            request.AddHeader("Content-Type", "application/x-www-form-urlencoded");

            var response = await _restClient.ExecuteAsync(request);

            if (response.IsSuccessful)
            {
                var json = JObject.Parse(response.Content);
                return json["access_token"]?.ToString();
            }
            else
            {
                // 输出完整响应内容,便于排查问题
                Console.WriteLine($"Token获取失败: {response.StatusCode} - {response.StatusDescription}");
                Console.WriteLine($"响应内容: {response.Content}");
                return null;
            }
        }

        private async Task<string> MakeAuthenticatedRequestAsync(string token)
        {
            var request = new RestRequest(ApiUrl, Method.Get);
            request.AddHeader("Authorization", $"Bearer {token}");

            var response = await _restClient.ExecuteAsync(request);

            if (response.IsSuccessful)
            {
                return response.Content;
            }
            else
            {
                Console.WriteLine($"API请求失败: {response.StatusCode} - {response.StatusDescription}");
                Console.WriteLine($"响应内容: {response.Content}");
                return null;
            }
        }
    }
}

关键修改说明

  1. 补充ApiUrl常量:添加目标API的地址,确保代码可编译运行
  2. 调整Token请求参数传递方式:使用ParameterType.RequestBody明确将参数放入请求体,符合OAuth2 client_credentials模式的要求
  3. 增强错误排查信息:在请求失败时打印完整响应内容,帮助定位是参数错误、权限问题还是API端的其他问题
  4. 复用RestClient:在SetUp方法中初始化RestClient,避免每次请求重复创建实例,提升测试执行效率
  5. 简化方法参数:因为类中已有常量,去掉GetBearerTokenAsync和MakeAuthenticatedRequestAsync的冗余参数,让代码更简洁

额外排查建议

  • 确认TokenUrl、ClientId、ClientSecret的正确性,可先用Postman手动调用Token接口验证是否能获取到Token
  • 检查目标API的鉴权要求,部分API可能要求Token的受众(Audience)或权限范围(Scope),若需额外参数,在Token请求中添加对应的scope参数
  • 若使用的是RestSharp最新版本,可考虑使用AddStringBody方法构建x-www-form-urlencoded格式的请求体,写法更直观:
    request.AddStringBody("grant_type=client_credentials&client_id=123456789&client_secret=1000222", ContentType.UrlEncoded);
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 17:48:21