PDA

Ver la Versión Completa : API REST con problema en BODY


mjjj
14-05-2020, 02:55:59
Estimados, espero me puedan ayudar.
Estoy utilizando Delphi XE5 para realizar consultas a una API REST, con los componentes RESTRequest, RESTClient, RESTResponse, RESTResponseDAtaSetAdapter y OAuth2Authenticator y todo va bien hasta que tengo que pasarle un texto en Body raw como sigue:

{
"auth": {
"pass": {
"rut": "12345678-0",
"clave": "123456"
}
}
}

Si consumo otros servicios publicados en la misma API, pero que no necesite el Body funciona de maravilla.

Alguien me puede ayudar con esto ??

Tengo la certeza que la API funciona bien, porque la he probado con la herramienta Postman.

mjjj
14-05-2020, 03:51:50
Esto es lo que escribe el tutorial de la API:

Se debe enviar mediante POST un JSON con el objeto auth.pass que contendrá las credenciales.

{
"auth": {
"pass": {
"rut": "12345678-0",
"clave": "123456"
}}}


He intentado con esto, pero no resulta

RESTrequest1.ClearBody;
RESTrequest1.AddBody('{"auth": {"pass": {"rut": "12345678-0","clave": "123456"}}}', ctAPPLICATION_JSON);
RESTrequest1.Execute;


Favor alguna idea ???

mjjj
16-05-2020, 06:55:42
Sigo intentado conectarme, pero no he podido.
He intentado conectarme con REST Debugger, pero no he podido ya que me arroja el error 401, pero si lo hago desde el mismo Delphi si puedo ya que aquí existe la característica "TokenType" del TOAuth2Authenticator, si se cambia esa característica al valor "ttBEARER" logras conectarte sin problema en aquellas consultas que no necesita Body Custom.

He generado el JSON con el siguiente código y lo he agregado al request, pero sigue sin funcionar.


var
Obj, ObjCons, ObjIpp: TJSONObject;

begin

ObjCons := TJSONObject.Create;
ObjCons.AddPair('rut', TJsonString.Create('12345678-0'));
ObjCons.AddPair('clave', TJsonString.Create('prueba'));

ObjIpp := TJSONObject.Create;
ObjIpp.AddPair('pass',ObjCons);

Obj := TJSONObject.Create;
Obj.AddPair('auth',ObjIpp);

RESTrequest1.ClearBody;
RESTrequest1.AddBody(Obj);
RESTrequest1.Execute;

end;


Que estaré haciendo mal ??
Será que esta característica (custom body) se agrega en otra parte ??

También he intentado esto, pero sigo con el mismo error 500 (Internal Server Error).

var
Obj, ObjCons, ObjIpp: TJSONObject;

begin

ObjCons := TJSONObject.Create;
ObjCons.AddPair('rut', TJsonString.Create('12345678-0'));
ObjCons.AddPair('clave', TJsonString.Create('prueba'));

ObjIpp := TJSONObject.Create;
ObjIpp.AddPair('pass',ObjCons);

Obj := TJSONObject.Create;
Obj.AddPair('auth',ObjIpp);


RESTrequest1.Params.Clear;
RESTrequest1.Params.Add;
RESTrequest1.Params[0].ContentType := ctAPPLICATION_JSON;
RESTrequest1.Params[0].Kind := pkREQUESTBODY;
RESTrequest1.Params[0].Value := obj.ToString;


RESTrequest1.Execute;

end;


Esta correcto la forma de armar el JSON ??
Favor su ayuda, llevo muchas horas sin lograr nada.

Les dejo la URL de la API LibreDTE.
https://documenter.getpostman.com/view/5911929/SWLiYkK9?version=latest

gatosoft
18-05-2020, 00:07:49
No veo en la documentación cuál es la URL del "recurso" para la autenticación.

Si dice que la ruta base es: https://api.libredte.cl/api/v1/sii, pero hace falta el recurso. Algo como:

https://api.libredte.cl/api/v1/sii/Login

Por otro lado, no se porque hablas de Autenticación oAuth2, y por otro lado estas intentando la autenticación mediante rut/password.

No nos indicas si estas haciendo la autenticación via POST o GET... y no vemos a que URL estas haciendo la petición.

Cualquiera de las dos formas deberias poder hacerlo por el REST Debugger, que tambien permite enviar autenticaciones con token BEARER tipo oAuth2.

intenté la autenticación via REST Debugger y no es posible. La extensión de ejemplo que tiene para PHP parte del hecho que ya tienes un token, y no realiza autenticación.

mjjj
18-05-2020, 16:00:54
Hola gatosoft y gracias por su respuesta.

Te cuento oAuth2 es para aytenticarse en la API con un token y rut y clave son las credenciales para el SII, lo cual debe ir en custom body.
He logrado conectarme y obtener respuesta de aquí, ya que no es necesario agregar nada en cuerpo, pero si es necesario autenticarme en la API con el token.


curl --location --request GET 'https://api.libredte.cl/api/v1/sii/indicadores/uf/anual/2020' \
--header 'Accept: application/json'


Pero cuando intento consultar por esta me arroja un error interno del servidor, ya que no se como agregar las credenciales del SII en el cuerpo.


curl --location --request POST 'https://api.libredte.cl/api/v1/sii/mipyme/recibidos/xml//96800570-7/33/20043280' \
--header 'Accept: application/json' \
--header 'Content-Type: application/json' \
--data-raw '{
"auth": {
"pass": {
"rut": "",
"clave": ""
}
}
}
'


He intentado con los códigos escritos en respuesta anterior, pero no me ha resultado.
Favor su ayuda.

gatosoft
18-05-2020, 17:34:02
Ok, viendo la documentación, veo que no existe en realidad una autenticación por RUT-CLAVE... el API, ofrece la posibilidad de hacer peticiones y en el Body enviar las credenciales (mal, pero...)


bueno, tu dices que recibes un internal error, pero yo recibo, con la misma petición este mensaje 401 (UnAuthorized por estándar). El mensaje retornado es:

{"message":"Unauthenticated."}{
"message": "Server Error"
}

Esto quiere decir que si está llegando al server y está validando la petición y concluye que no estas autenticado....

Yo estoy enviando una petición post con un body asi:

{
"auth": {
"pass": {
"rut": "12345678-0",
"clave": "12345678"
}
}
}

La URL: https://api.libredte.cl/api/v1/sii/mipyme/recibidos/xml/96800570-7/33/20043280/1

Es posible que el mensaje llegue porque las credenciales no sean válidas y el error no sea claro en este sentido...

¿Lo estas intentando por PostMan?, ¿por el REST Tool de delphi?... seria bueno ver una foto de la peticiñon y del error..

mjjj
19-05-2020, 00:00:56
Si he logrado conectarme sin problema con Postman.
Agrega este token y veras que te funciona.

eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9.eyJhdWQiOiIxIiwianRpIjoiMWNhNjE2OTZmNWYzNTU3YzQ0YmVlYzVjZGQ2ZDE zYTMxYmNiMDc0YzNhOWY4NmZlMjIyZjAwN2U3NmQyOTkyNTFjMTRmMGU2MmVmNWE0ZDgiLCJpYXQiOjE1ODk1OTY0OTcsIm5iZiI 6MTU4OTU5NjQ5NywiZXhwIjoxNjIxMTMyNDk3LCJzdWIiOiIxMTQiLCJzY29wZXMiOltdfQ.kYi4q8IjmtwXFhnvUCiniDgwP4ts 6VHphYHDHTEbAzD5vmYwZi9fF5o55lMLtPqUovoQKIDQHB3vT-tU4PpC_AJH2Ea65tKq4wgHVHWyXkCKuWST0-hC-anAOrMpTJsO45Pcuye5kLgHndZExVwe-XegrgsPEw2AYWNmMra7EagnMQfBwzXyE6EDk6Ql9gZPG07GtQp7FGEWWR04EScFbotuygT8eXgbfRDNwwpONQ0IjeBIhkfRPrMIh qmr3X1myosNzJ-WOiFTCTjSOrqNLW-MJ-riZDJcB93OGKI43KyvB4ng0_-4qz5PnJlf1snSbNUVlKqNeseWXQmCGPW1wSrDP_WKzSUmAHz_ySGJD7XFYX155VBRuy9JJW2CVsv4zGFUgwErsNiXzQSUGaghtsE qz9_AhxsKXOeyJgLPlcSPEO6oEGg73KGkcCEH1Kj9FI5r0jy1IzPW4nreBIoilMgGp4PvjzE_voekgd9xN-ypz3FSGmSdN073ceBpGze9-Hasj7gMsGxoqgaen5DkPCNLDX5xmTv7gSn2ViEV-lhs503PheQ_WmukugEqsikrlPah3tOmQqUnHlV2mFBvzzUolN055tJcSacXTjqsZKcTbFBzXcWLHSnCtF0wWx57Doyt_Tkk-JwQ2Atedy3m3_oI4zYFHhOxUJMLM7CmE7o

En el componente TOAuth2Authenticator, cambia la propiedad de TokenTypo por ttBEARER y podrás hacer consultas que no requieran nada en el cuerpo, por ejemplo:

GET https://api.libredte.cl/api/v1/sii/indicadores/uf/anual/2020

El problema surge cuando necesito agregar en el cuerpo las credenciales del SII, aquí es cuando me arroja el error interno, por ejemplo:

POST https://api.libredte.cl/api/v1/sii/rcv/compras/resumen/12345678-0/202003/REGISTRO?formato=json&certificacion=0

Como agrego al cuerpo JSON requerido ??


{
"auth": {
"pass": {
"rut": "12345678-0",
"clave": "12345678"
}
}
}


Este código no resulta


var
Obj, ObjCons, ObjIpp: TJSONObject;

begin

ObjCons := TJSONObject.Create;
ObjCons.AddPair('rut', TJsonString.Create('12345678-0'));
ObjCons.AddPair('clave', TJsonString.Create('prueba'));

ObjIpp := TJSONObject.Create;
ObjIpp.AddPair('pass',ObjCons);

Obj := TJSONObject.Create;
Obj.AddPair('auth',ObjIpp);

RESTrequest1.ClearBody;
RESTrequest1.AddBody(Obj);
RESTrequest1.Execute;

end;


Ni tampoco este:


var
Obj, ObjCons, ObjIpp: TJSONObject;

begin

ObjCons := TJSONObject.Create;
ObjCons.AddPair('rut', TJsonString.Create('12345678-0'));
ObjCons.AddPair('clave', TJsonString.Create('prueba'));

ObjIpp := TJSONObject.Create;
ObjIpp.AddPair('pass',ObjCons);

Obj := TJSONObject.Create;
Obj.AddPair('auth',ObjIpp);


RESTrequest1.Params.Clear;
RESTrequest1.Params.Add;
RESTrequest1.Params[0].ContentType := ctAPPLICATION_JSON;
RESTrequest1.Params[0].Kind := pkREQUESTBODY;
RESTrequest1.Params[0].Value := obj.ToString;


RESTrequest1.Execute;

end;



No estoy muy instruido en JSON, está bien generado con los códigos que escribo ??
Espero me puedan ayudar !!