How to create HTTP Header for eBay Browse API Func

2019-07-30 05:51发布

问题:

I am trying to get a Product Review Rating through eBay's Browse API. Here is my code for this function:

sHeaders := TStringList.Create;
sHeaders.Add('X-EBAY-C-ENDUSERCTX=' + '"affiliateCampaignId=' + '533xxxxxxx"');
objIdHTTP.Request.CustomHeaders.AddStdValues(sHeaders);
sResponse := objIdHTTP.Get('https://api.sandbox.ebay.com/buy/browse/v1/item/v1|123456789|0');

But I get a Socket Error 10054 when I test this code.

It might be something wrong with the customer header part, but I can't figure out how to make it work.

Could anyone please help me with any mistakes?

Here is a link to eBay's API document that I am referring to:

Browse API | Use request headers

UPDATE: here is my updated code:

objIdHTTP.Request.CustomHeaders.AddValue('X-EBAY-C-ENDUSERCTX', 'affiliateCampaignId=' + '533xxxxxxx');
sResponse := objIdHTTP.Get('https://api.sandbox.ebay.com/buy/browse/v1/item/v1|123456789|0');

It still has the same error.

I tested the URL link in Postman, and I got an error message as below:

{
  "errors": [
      {
        "errorId": 1002,
        "domain": "OAuth",
        "category": "REQUEST",
        "message": "Missing access token",
        "longMessage": "Access token is missing in the Authorization HTTP request header."
      }
  ]
}

Many IDs exist, such as AppID, DevID, CerID, OAuthToken (9583 characters), Token for Store (3343 characters), EPN Campaign (already included in this URL header).

I tried with X-EBAY-API-IAF-TOKEN: OAuthToken, but it replied with the same error message.

UPDATE:

Thanks for all help in StackOverflow, specailly Remy Lebeau. Finally I got working codes as below:

with objHTTP.Request.CustomHeaders do begin
  Clear;
  FoldLines := False;
  Values['Content-Type'] := 'application/x-www-form-urlencoded';
  Values['Authorization'] := 'Basic ' + 'myAuthCode';
end;
xRequestBody := TStringStream.Create('{"Authorization":"Basic ' + 'myAuthCode' + '"' + ','
                                   + ' "Content-Type:' + 'application/x-www-form-urlencoded' + '"}',
                                     TEncoding.UTF8);

sResponse := objHTTP.Post(sURL, xRequestBody);

I still have no idea why indy HTTP needs to assign ContentType and Authorization twice but these codes work well for me now.

UPDATE: Refer to advice from Remy Lebeau, ContentType is assigned to idHTTP.Request directly and codes are updated again as below:

with objHTTP.Request do begin
  Clear;
  ContentType := 'application/x-www-form-urlencoded';
  CustomHeaders.FoldLines := False;
  CustomHeaders.Values['Authorization'] := 'Basic ' + myAuthCode;
end;
xRequestBody := TStringStream.Create('{"Authorization":"Basic ' + myAuthCode + '"}', TEncoding.UTF8);

sResponse := objHTTP.Post(sURL, xRequestBody);

Let's go back to my start point. Now I start to struggle with GET to have Authorization, code is modified from first part to those (code is updated again in order to capture http request):

objHTTP.Intercept := xIdLogDebug;
with objHTTP.Request.CustomHeaders do begin
  Clear;
  FoldLines := False;
  Values['X-EBAY-C-ENDUSERCTX'] := 'affiliateCampaignId=' + '533xxxxxxx';
  Values['Authorization'] := 'Bearer ' + myToken;
  Values['Postman-Token'] := '65546b71-aef8-422e-916d-93b75ddd9de2,a0687ba7-e142-4849-8288-a8f89b66f253';
  Accept := '*/*';
  UserAgent := 'PostmanRuntime/7.13.0';
  CacheControl := 'no-cache';
  AcceptEncoding := 'gzip, deflate';
  Connection := 'keep-alive';
end;

with objHTTP do begin
  AllowCookies := True;
  CookieManager  := objCookie;
end;

Result := objHTTP.Get('https://api.sandbox.ebay.com/buy/browse/v1/item/v1|123456789|0');

It still gets Socket Error 10054. I tested this URL in Postman and it works fine. The only different I can point out is that there is one TYPE option for Authorization inside Postman, and it is selected as "OAuth 2.0".

So, how to assign authorization to Indy HTTP for GET? Might be something like RequestBody in POST.

UPDATE:

Here is received data by POST call through IndyHTTP:

HTTP/1.1 200 OK
Content-Length: 1905
Date: Sat, 01 Jun 2019 11:09:08 GMT
RlogId: t6ldssk%28ciudbq%60anng%7Fu2h%3F%3Cwk%7Difvqn*14%3F0512%29pqtfwpu%29pdhcaj%7E%29fgg%7E%606%28dlh-16b12ba9d25-0x4fd7e
Set-Cookie: ebay=%5Esbf%3D%23%5E;Domain=.ebay.com;Path=/
Set-Cookie: dp1=bu1p/QEBfX0BAX19AQA**5ed39054^;Domain=.ebay.com;Expires=Mon, 31-May-2021 11:09:08 GMT;Path=/
X-Content-Type-Options: nosniff
X-EBAY-C-VERSION: 1.0.0
X-EBAY-REQUEST-ID: 16b12ba9d1f.a0962ac.25e7e.ff9d75b3!/identity/v1/oauth2/!10.9.98.172!esbnewesbngcos[]!token.clientcredentials!10.9.107.144!r1oauth-envadvcdhidzs5k[IdentityCDSClient[!ClientDetailResourceV1.getClientDetail!10.199.16.86!r1oauthclnt-envjiwv5gtvevlbi[]]]
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
Content-Type: application/json
Connection: keep-alive

{"access_token":"v^1.1#i^............","expires_in":7200,"token_type":"Application Access Token"}

This is captured request by GET call (run after POST) from IndyHTTP (converted from TIdBytes to String):

GET /buy/browse/v1/item/v1|123456789|0 HTTP/1.1
Content-Type: application/json
X-EBAY-C-ENDUSERCTX: affiliateCampaignId=533xxxxxxx
Authorization: Bearer v^1.1#i^............
Postman-Token: 65546b71-aef8-422e-916d-93b75ddd9de2,a0687ba7-e142-4849-8288-a8f89b66f253
Host: api.sandbox.ebay.com
Accept: */*
Accept-Encoding: gzip, deflate, identity
User-Agent: PostmanRuntime/7.13.0
Cookie: dp1=bu1p/QEBfX0BAX19AQA**5ed3395b^; ebay=%5Esbf%3D%23%5E

And this is code copied from Postman:

GET /buy/browse/v1/item/v1|123456789|0 HTTP/1.1
Host: api.sandbox.ebay.com
X-EBAY-C-ENDUSERCTX: affiliateCampaignId=533xxxxxxx
Authorization: Bearer v^1.1#i^............
User-Agent: PostmanRuntime/7.13.0
Accept: */*
Cache-Control: no-cache
Postman-Token: 65546b71-aef8-422e-916d-93b75ddd9de2,a0687ba7-e142-4849-8288-a8f89b66f253
Host: api.sandbox.ebay.com
cookie: ebay=%5Esbf%3D%23%5E; dp1=bu1p/QEBfX0BAX19AQA**5ed2398a^bl/AU60b36d0a^; s=; nonsession=CgADKACBmVweKZWYwZThjOGQxNmEwYWMxZTQ2MDNlNGJhZmZkYjQzNTT+86sJ
accept-encoding: gzip, deflate
Connection: keep-alive
cache-control: no-cache

I am struggling which parameter makes IndyHTTP got #10054 error from server.

Thanks.