0

我为我正在开发的 Bot App 创建了一个接口来使用 Refit 调用 Prestashop API。为了调用 API,您需要使用我拥有的 Prestashop API 密钥进行身份验证。要使用浏览器进行查询,我只需要使用以下格式调用 url:

$"https://{ApiKey}@{mypage}.com/api"

@它使用签名前指定的 Api Key 进行身份验证。要定义改装,HttpClient我在 Startup.cs 中使用此代码:

// This is the ApiUrl from the appsettings.json file
var apiUrl = Configuration.GetSection("PrestashopSettings").GetSection("ApiUrl").Value;

// We add the Api and specify the de/serialization will be XML
services.AddRefitClient<IPrestashopApi>(
    new RefitSettings
    {
        ContentSerializer = new XmlContentSerializer()
    })
    .ConfigureHttpClient(c => c.BaseAddress = new System.Uri(apiUrl));

然后我将 API 注入我的一个类并调用它的一个函数。URL 似乎是正确的,如果我将完整的 URL(基础 + [Get] url)粘贴到浏览器,它会正确返回 XML。但是当我从应用程序中执行此操作时,它会返回一个异常:

Microsoft.Bot.Builder.Integration.AspNet.Core.BotFrameworkHttpAdapter:Error: Exception caught : Refit.ApiException: Response status code does not indicate success: 401 (Unauthorized).
   at Refit.RequestBuilderImplementation.<>c__DisplayClass14_0`2.<<BuildCancellableTaskFuncForMethod>b__0>d.MoveNext() in D:\a\1\s\Refit\RequestBuilderImplementation.cs:line 274
--- End of stack trace from previous location where exception was thrown ---

使用 Refit 的 HttpClient 进行身份验证的正确方法是什么?难道我做错了什么?

更新:

所以我尝试了这个:

public class HttpAuthentication : HttpClientHandler
{
    private readonly string Token;
    public HttpAuthentication(string token)
    {
        Token = token ?? throw new ArgumentException(nameof(token));
    }

    protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
    {
        var token = Token;
        request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
        return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
    }
}

这段代码在我的Startup.cs

var apiKey = Configuration.GetSection("PrestashopSettings").GetSection("ApiKey").Value;
var storeUrl = Configuration.GetSection("PrestashopSettings").GetSection("StoreUrl").Value;

// We add the Api and specify the de/serialization will be XML, and we specify the Authentication Client.
services.AddRefitClient<IPrestashopApi>(
    new RefitSettings
    {
        ContentSerializer = new XmlContentSerializer()
    })
    .ConfigureHttpClient((c) => c.BaseAddress = new System.Uri(storeUrl))
    .ConfigureHttpMessageHandlerBuilder((c) => new HttpAuthentication(apiKey));

而且我仍然收到相同的错误消息。

4

2 回答 2

0

像这样创建类:

 public class AuthenticatedHttp : HttpClientHandler
    {
        private readonly string Token;
        public AuthenticatedHttp(string token)
        {
            if (token == null)
            {
                throw new ArgumentNullException(nameof(token));
            }
            this.Token = token;
        }
        protected override async Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
        {
            // See if the request has an authorize header
            var token = this.Token;
            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", token);
            return await base.SendAsync(request, cancellationToken).ConfigureAwait(false);
        }
    }

并将令牌发送到此类:

var token = await GetAccessToken();
            var RestReq = RestService.For<IPerson>(new HttpClient(new AuthenticatedHttp(token)) { BaseAddress = new Uri(Url) });
于 2019-11-20T11:20:12.183 回答
0

好吧,我最后想通了。首先,我想指出有两种解决方案。

第一个解决方案

您实际上可以使用您的 API 密钥作为请求参数进行身份验证,其密钥是ws_key,因此您可以发送如下调用:

"https://api.yourapiaddress.com/yourentity?ws_key={API KEY HERE}"

第二种解决方案

这是我选择的,只是添加了一个Header Parameter。发现 Prestashop API 1.7 使用基本授权,API 密钥作为用户名和空白密码,所以我在下面构建了这样的标题Startup.cs

// Encode your Api Key
String encoded = Convert.ToBase64String(System.Text.Encoding.GetEncoding("ISO-8859-1").GetBytes(apiKey));

// Add the API to DI in Dialog classes
services.AddRefitClient<IPrestashopApi>(
    new RefitSettings
    {
        ContentSerializer = new XmlContentSerializer()
    })
    .ConfigureHttpClient((c) => c.BaseAddress = new Uri(storeUrl))
    .ConfigureHttpClient((c) => c.DefaultRequestHeaders.Add("Authorization", "Basic " + encoded));

我使用了 Retrofit 的 ConfigureHttpClient 函数,但实际上你可以通过创建自己的 HttpClient 对象并像这样配置 DefaultRequestHeaders 来实现相同的目的。

于 2019-11-21T13:36:03.943 回答