Foros Club Delphi

Foros Club Delphi (https://www.clubdelphi.com/foros/index.php)
-   Internet (https://www.clubdelphi.com/foros/forumdisplay.php?f=3)
-   -   Problemas con Request POST a Woocommerce (https://www.clubdelphi.com/foros/showthread.php?t=94398)

XusF 23-01-2020 09:47:46

Problemas con Request POST a Woocommerce
 
Buenos días,

Estoy intentando hacer una petición REST a Woocommerce, concretamente intentando actualizar stocks de la tienda. La conexión con la API la he conseguido hacer, de hecho hago peticiones GET sin problema, pero al hacer un POST siempre me da un error:

Código:

'{"code":"rest_invalid_json","message":"Ha pasado un cuerpo JSON no v\u00e1lido.","data":{"status":400,"json_error_code":4,"json_error_message":"Syntax error"}}'
La autenticación es OAuth1. Estoy probando con un JSON muy sencillo que es el siguiente:

Código:

{
    "update": [
        {
            "id": 11563,
            "stock_quantity": 20
        }
    ]
}

Os enseño el código que estoy utilizando:

Código:

procedure TdmoDataModule.ActualizarStockWordpress;
var
  body: TJSONObject;
  updates: TJSONArray;
  product: TJSONObject;
  value: TJSONValue;
  s: string;
  lparam: TRESTRequestParameter;
  i: integer;

//  param: TJSONRequestParameter;

begin
  qryArticulos.Close;
  qryArticulos.Open;
  qryArticulos.First;

  body := TJSONObject.Create;
  updates := TJSONArray.Create;

  try
    while not qryArticulos.Eof do
    begin
      product := TJSONObject.Create;

      product.AddPair('id', TJSONNumber.Create(qryArticulos.FieldByName('CODIGO').AsInteger));
      product.AddPair('stock_quantity', TJSONNumber.Create(qryArticulos.FieldByName('STOCK_ACTUAL').AsInteger));
      updates.AddElement(product);

      qryArticulos.Next;
    end;

    body.AddPair(TJSONPair.Create('update', updates));

    showMessage(body.ToString);

    with dmoREST do
    begin
      RESTRequestProductsBatch.Params.Clear;

      RESTRequestProductsBatch.AddParameter(OAUTH_CONSUMER_KEY, OAUTH_CONSUMER_KEY_VALUE);
      RESTRequestProductsBatch.AddParameter(OAUTH_SIGNATURE_METHOD, OAUTH_SIGNATURE_METHOD_VALUE);
      RESTRequestProductsBatch.AddParameter(OAUTH_NONCE, OAuth1Authenticator1.nonce);
      RESTRequestProductsBatch.AddParameter(OAUTH_TIMESTAMP, OAuth1Authenticator1.timeStamp.DeQuotedString);
      RESTRequestProductsBatch.AddParameter(OAUTH_VERSION, OAUTH_VERSION_VALUE);
      s := OAuth1Authenticator1.SigningClass.BuildSignature(RESTRequestProductsBatch, OAuth1Authenticator1);
      RESTRequestProductsBatch.AddParameter(OAUTH_SIGNATURE, s);

      RESTRequestProductsBatch.AddBody(body);

      RESTRequestProductsBatch.Execute;
      showMessage(RESTResponseProductsBatch.Content);
    end;

  finally
    body.Free;
  end;
end;


Para hacer las peticiones GET tengo que añadir todos los parámetros que veis arriba por código, sino no funciona. Aquí he hecho lo mismo, y de hecho el error que me da no es de autenticación, sino que para ser que el error está en el JSON o en alguna propiedad del parámetro "body". He probado muchas combinaciones pero ninguna me ha dado resultado.

A ver si alguien es capaz de echarme una mano.

Muy agradecido,

Xus

MicrodeltaAmpos 17-04-2020 12:37:43

La solución a este problema ha sido añadir al fichero .htacces del servidor WEB donde está el wordpress el siguiente texto:

Código:

RewriteRule ^wp-json/.* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization},L]

El problema venía dado al autenticar con auth1 a través de REST Debuger, la cabecera no llegaba completa y por tanto no había forma de validar acceso. Con esta linea de código permitimos la autorización básica y entonces si que ya podemos realizar los post y puts correspondientes.

fmira 06-02-2021 19:31:36

Buenas tardes,

Tengo el mismo problema que Xus, pero la solución que aporta MicrodeltaAmpos no me funciona.

No tengo ningún problema para hacer GET pero con un POST siempre me da un error u otro, cuando no el que el JSON no es válido es que la firma no coincide, pero no logro crear un artículo.

Código:

OAuth1Authenticator1:=TOAuth1Authenticator.Create(self);
 OAuth1Authenticator1.ConsumerKey := ck;
 OAuth1Authenticator1.ConsumerSecret := cs;
 OAuth1Authenticator1.SigningClassName := 'TOAuth1SignatureMethod_HMAC_SHA1';
 OAuth1Authenticator1.CallbackEndpoint := '';

 Restclient1.BaseURL :=  miurlapi;
 RESTRequest1.Resource := 'products';
 RESTRequest1.Method := TRESTRequestMethod.rmpost;


 RESTRequest1.AddParameter('oauth_consumer_key', ck);
 RESTRequest1.AddParameter('oauth_consumer_secret',cs);
 RESTRequest1.AddParameter('oauth_signature_method', 'HMAC-SHA1');
 RESTRequest1.AddParameter('oauth_nonce', OAuth1Authenticator1.nonce);
 RESTRequest1.AddParameter('oauth_timestamp',
  OAuth1Authenticator1.timeStamp.DeQuotedString);
 RESTRequest1.AddParameter('oauth_version', '1.0');
 s := OAuth1Authenticator1.SigningClass.BuildSignature(RESTRequest1,OAuth1Authenticator1);
 RESTRequest1.AddParameter('oauth_signature', s);

 RESTRequest1.Addbody(mijson.tostring);  // tampoco con mijson ni con mijoson.tojson
 RESTRequest1.Execute;

Llevo varios dias peleando con ello, tambien he probado con TidHttp de Indy, sin resultado.
Si modifico el .htaccess como dice @MicrodeltaAmpos me da error de página no existe, es más incluso picando la url en el chrome me dice no mismo "Not Found"


Se agradece mucho una ayuda.


La franja horaria es GMT +2. Ahora son las 02:05:52.

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi