4

我正在尝试为已向我提供 swagger.json 文件的 API 生成 C# 客户端,位于此链接;

https://api.ekm.net/swagger/v1/swagger.json

使用 NSwagStudo 应用程序,我可以导入配置文件并生成一个名为 Client.cs 的文件,该文件实现了一个名为 Client 的类,并且它具有与 API 匹配的方法。

但是,当我调用任何方法时,我会收到“未经授权”异常,并且找不到任何方法向客户端或与其他身份验证方法类似的任何人提供 OAuth 密钥和秘密。

检查 swagger 配置文件确实表明 OAuth 被指示为身份验证方法,如下所示;

"securityDefinitions": {
    "OAuth": {
        "flow": "accessCode",
        "authorizationUrl": "https://api.ekm.net/connect/authorize",
        "tokenUrl": "https://api.ekm.net/connect/token",
        "scopes": {
            "tempest.customers.read": "Read a shop's customers.",
            "tempest.customers.write": "Modify a shop's customers.",
            "tempest.orders.read": "Read a shops orders.",
            "tempest.orders.write": "Modify a shop's orders.",
            "tempest.products.read": "Read a shop's products.",
            "tempest.products.write": "Modify a shop's products.",
            "tempest.categories.read": "Read a shop's categories.",
            "tempest.categories.write": "Modify a shop's categories.",
            "tempest.settings.orderstatuses.read": "Read a shop's order statuses.",
            "tempest.settings.domains.read": "Read a shop's domains."
        },
        "type": "oauth2",
        "description": "In order to ensure the safety of our users data, we require all partner applications to register via the [Partner Dashboard](https://partners.ekm.net/). Once registered, partners are provided with an application key, which can be used during an OAuth2 handshake to create a token. This token can then used to make requests on behalf of a merchant."
    }
},

我的测试代码如下;

static void Main(string[] args)
{
    var swagClient = new Client();

    var ords = swagClient.ApiV1OrdersGetAsync(1, 100).Result;  // This call throws SwaggerException: Unauthorized
}

该类Client没有任何明显的方法或属性来设置安全值或任何构造函数参数。

有没有人有一个如何实现这一目标的例子?

4

1 回答 1

5

我同意。它不只是接受某种“在此处插入 JWT”,这有点奇怪。

无论如何,这就是我修复它的方式:

注入HttpClient

勾选 NSwagStudio 中名为“Inject HttpClient via constructor”的框

自定义消息处理程序

引入一个自定义HttpMessageHandler

internal class AuthTokenHttpMessageHandler: HttpClientHandler
{
    private readonly Action<HttpRequestMessage, CancellationToken> _processRequest;

    public AuthTokenHttpMessageHandler(Action<HttpRequestMessage, CancellationToken> processRequest)
    {
        _processRequest = processRequest;
    }

    protected override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        _processRequest(request, cancellationToken);
        return base.SendAsync(request, cancellationToken);
    }
}

此处理程序接受一个委托,您可以在其中提供您的 JWT。

与您的客户集成

using System.Net.Http;
using System.Net.Http.Headers;
using System.Threading.Tasks;

public class MyService : IDisposable
{
    private readonly AuthTokenHttpMessageHandler _messageHandler;
    private readonly HttpClient _httpClient;
    private readonly MyNSwagClient _client;

    public MyService()
    {
        _messageHandler = new AuthTokenHttpMessageHandler((req, _) =>
        {
            req.Headers.Authorization = new AuthenticationHeaderValue("bearer", "your token goes here");
        });
        _httpClient = new HttpClient(_messageHandler);

        _client = new MyNSwagClient(_httpClient);
    }

    public async Task<SomeModel> GetStuffAsync(string paramenter1)
    {
        return await _client.StuffGetAsync(parameter1);
    }

    public void Dispose()
    {
        _httpClient?.Dispose();
        _messageHandler?.Dispose();
    }
}

我希望这可以帮助你

于 2018-11-12T09:11:28.833 回答