Saltar a contenido

Json API

The development of eFlow does not have a standard API interface model with a model of tokens and routes with data embedded in the routes, due to its origins from very early developments on the Internet.

However, an effort has been made to provide an interface that is as similar and functional as possible using HTTP transactions: GET, DELETE, PUT and POST.

GET, DELETE Transactions

In this case the parameters are sent encoded in URL Encoding in the initial and traditional standard by adding the parameters after the route using the question mark delimiter

curl "https://eflow.empresa.com.mx/api-cgi/eflow/folio?p=2&f=868"

This example calls the API entry point with the parameters: p = 2 and f = 868

POST, PUT Transactions

curl -X POST https://eflow.empresa.com.mx/cgi/api/getTicket \
-H 'Content-Type: application/json' \
-d '{"account":"usuario","passwd":"contraseña"}'

Execution of defined actions

Because there are no routes in the URL to define actions to be performed (for example: add, delete, update, consult, etc.)

In POST calls, it has been created as a standard to add a command to the transaction data; which defines the action to be performed.

curl -X POST https://eflow.empresa.com.mx/cgi/api-bin/eflow/folio \
-H 'Content-Type: application/json' \
-d '{"cmd":"cancel","process":"4","station":"4","folio":"122"}'

API Authentication

There are 2 possible places to write your APIs

APIs for access within the eFlow flow

/home/eflowweb/cgi-bin/api/....

This is the standard place to put APIs that will be called from within the eFlow application itself. These routes are protected with a ticket that is assigned to the navigator at the time the entry was made. And since it is available in the browser, it is automatically sent to these routes in each transaction and does not need to do any type of registration process or obtaining tokens.

The life of the excess cookie in this path is valid as long as the user does not close or exit the application.

Use

We normally use this for popup development where we use reactive Javascript technologies like Vue, React, etc.

By placing our APIs in this place, the emerging applications developed will already have the necessary credentials to connect to our API without the need to create tickets or another authentication mechanism.

External access APIs

/home/eflowweb/api-bin/...

This is the place where APIs that are accessed from external portals should be installed and executed. This route is also protected by a ticket in the form of a cookie and you will need to submit the ticket in the cookie : auth_tkt to access the API entry point.

These credentials have a lifetime of 3 minutes and are used to perform one-time transactions in a subsequent call to an API within the previously mentioned route.

Use

These APIs are normally used when we make calls from other external servers.

Get temporary authentication token

To obtain a valid token you will need to call the API, we need to create a POST, with the account and password data of a valid eFlow user to the following entry point.

curl -X POST https://eflow.empresa.com.mx/cgi/api/getTicket \
-H 'Content-Type: application/json' \
-d '{"account":"usuario","passwd":"contraseña"}'

Response:

{"message":"ticket","data":{"auth_tkt":"NTdm.....XY="},"status":true}

This will return the token which you must include in your subsequent transaction in the cookie: auth_tkt

Example, curl

curl --cookie "auth_tkt=NTdm.....XY=" \
"https://eflow.miempresa.com.mx/api-bin/eflow/folio?p=2&f=868"

Apache configuration

To make the /api-bin path available, you will need to have a directory section similar to the following configured in your apache eflow.conf file:

<Directory "/home/installation-path/api-bin">
AllowOverride all
AuthType None
<RequireAny>
Require method OPTIONS
require valid-user
</RequireAny>
TKTAuthLoginURL /public/login.json
TKTAuthTimeoutURL /public/timeout.json
TKTAuthIgnoreIP on
TKTAuthTimeout 180
TKTAuthCookieExpires 180s
Options ExecCGI
SSLOptions +StdEnvVars
</Directory>

And in the VirtualHost section add an access alias to the route

<VirtualHost *:443>
...
ScriptAlias /api-bin/ "/home/installation-path/api-bin/"
...
</VirtualHost>

API : folio

https://eflow.empresa.com.mx/api-bin/eflow/folio

add

Add a new folio in a process

Parameters

  • process : Process number
  • station: Station number where to place the folio
  • label: optional. This label must be assigned to the folio for subsequent monitoring; if it is omitted, the standard label is assigned: process-folio
  • obj: optional, allows in the same transaction to fill in the data of the object associated with this folio
{
    "cmd": "add",
    "process": 1,
    "station": 1,
    "obj": {
        "ff_campo1": "valor1",
        "ff_campo2": "valor2",
        ...
    },
}

cancel

Cancel an existing folio

Parameters

  • process : Process number (mandatory)
  • station : Cancel folio located at this station (0 - all, n - specific station)
  • folio : eFlow internal folio number
  • label: Optional, if no folio is supplied, the user's label must be reported
  • force : [0,1] Optional, delete all parallels (mandatory if station is not defined), delete even if station is not authorized to cancel
{
    "cmd": "cancel",
    "process": 1,
    "station": 0,
    "folio" : 111,
    "force": 1,
}

finish

End folio in a process

Parameters

  • process : Process number (mandatory)
  • station: Station number where the folio must be located (mandatory)
  • folio : eFlow internal folio number (optional recommended)
  • label: Optional, if no folio is supplied, the user's label must be reported
{
    "cmd": "finish",
    "process": 1,
    "station": 1,
    "folio" : 111,
}

update

Update folio data in a process

Parameters

  • process : Process number (mandatory)
  • folio : eFlow internal folio number (required)
  • obj: Data to update (mandatory)
    "cmd": "update",
    "process": 1,
    "folio": 1,
    "obj": {
        "ff_dato1": "valor1",
        "ff_dato2": "valor2",
        ...
    },

get

Obtain registration data for a folio in the system

curl -L --cookie "auth_tkt=Y...jQ3" "https://eflow.miempresa.com.mx/api-bin/eflow/folio?p=2&f=868"

{"status":false,"message":"No tiene permisos para ver la historia de este folio."}%

curl "https://eflow.empresa.com.mx/api-cgi/eflow/folio?p=2&f=868"
curl "https://eflow.empresa.com.mx/api-cgi/eflow/folio?f=2-868"
curl "https://eflow.empresa.com.mx/api-cgi/eflow/folio?p=2&lable=AAC-0003444-444"

API development with perl

If you need to develop your own APIs, eFlow offers a library to facilitate the creation of APIs for Perl.

You can find a basic implementation in the directory: /home/eflowweb/cgi/api/eflow/test/echo.pl

Remove echo.pl

Even if the application does not transmit or deliver sensitive eFlow values, it is recommended to delete it after having studied it, or at least move it to a non-public area to prevent it from being accessed indiscriminately over the Internet.

Or at least edit it and assign a strong secret so you can use it while studying it.

JApi.pm

new : Crear objeto

$api = CGI::JApi->new({
    secret => 'secreto',
    url => ['https://sitio1.com.mx','https://sitio2.com.mx'],
    DELETE => \&del,
    GET => \&get,
    PUT => \&put,
    POST => \&post,
    pretty => 1,
});

Parameters

  • secret : If your API is located in the public section, it is recommended to assign a secret value to be shared between your consuming application and your api. When calling the API, if this option was configured, the library will check that the secret has been sent correctly in the transaction, if not, access will be denied to the rest of your program. (optional)
    • The secret must be sent as a cookie or in the request header
    • Header or cookie: japiauth: secret
    • If you are implementing a public api you will not need to write any secrets
  • url : If you are making cross calls between domains, you must define which domains are authorized to access this API, if you do not declare any arrangement, free access is allowed. (optional)
  • DELETE, GET, PUT, POST: Pointers to the routines that will handle the call of the corresponding method. If you do not declare a routine to handle access, an error will be raised that that option is not supported. There must be at least one pointer that resolves the call
  • pretty: Whether to format and indent the response json. It is only useful when we are in development and use utilities like curl to test, it makes the json response more readable in a terminal

Actions performed when creating object

  • Library reads call data
  • If the request is OPTIONS, validates valid URLs and returns access authorization or denial messages
  • If a secret exists, validate that the secret is the same in the call
  • Define call type: PUT, GET, POST, DELETE.
    • Read parameters and enter them in: $$api{data}{key}
    • If a json object is received, the elements are accessed using: $$api{data}{key}{..}{..}
  • If everything is ok return constructed object

Answers

All responses generated by the library are in the format.

{
    "status": [true,false],
    "message": "Mensage al usuario, error o exitoso",
    "data" : objeto,
}

General Methods

Method Parameters Use Example
MessageSuccess string Send message response with status = true $api->MessageSuccess("Everything went well")
MessageError string Send response message with status = false $api->MessageSuccess("Error accessing information")
MessageData string,object Send message response with status = true $api->MessageData("record",$ref_data)
ProcessRequest none Process call POST,GET,... $api->ProcessRequest()
me none Return user values if registered $me = $api->me()

Example echo

This small application placed in the public part of eFlow only returns what is sent to it as a response.

Curl examples, using Header and Cookie to send the secret

# Secret in header

curl -H "japiauth: secreto" \
-X POST https://eflow.empresa.com.mx/cgi/api/test/echo.pl \
-H 'Content-Type: application/json' \
-d '{"num":123456,"cliente":"municipio","donde":"1"}'

# Secreto en cookie

curl --cookie "japiauth=secreto" \
-X PUT https://eflow.empresa.com.mx/cgi/api/test/echo.pl \
-H 'Content-Type: application/json' \
-d '{"num":123456,"cliente":"municipio","donde":"1"}'

# Response

{"message":"Echo datos recibidos en data","status":true,"data":{"cliente":"municipio","num":123456,"donde":"1"}

# Examples , GET, DELETE, OPTIONS
curl -v -H "japiauth: secret" \
-X GET "https://eflow.miempresa.com/cgi/api/test/echo.pl?id=33"

curl -v -H "japiauth: secret" \
-X GET "http://eflow.miempresa.com/cgi/api/test/echo.pl"

curl -v -H "japiauth: secret" \
-X DELETE "https://eflow.miempresa.com/cgi/api/test/echo.pl?id=99"

curl -v -H "Origin: eflow.com.mx" \
-X OPTIONS "https://eflow.miempresa.com/cgi/api/test/echo.pl"

echo.pl

#!/usr/bin/perl

use Eflow::JApi;
use utf8;

our ($api);

$api = CGI::JApi->new({
    secret => 'mi secret',
    # url => ['https://sitio1.com.mx','https://sitio2.com.mx'],
    DELETE => \&del,
    GET => \&get,
    PUT => \&put,
    POST => \&post,
});

$api->ProcessRequest();

sub del {
    my $id = int($api->param('id'));
    $api->MessageSuccess("registro eliminado $id");
}

sub get {
    $api->MessageSuccess("registro obtenido $$api{data}{id}");
}

sub post {
    if ($$api{data}) {
        $api->MessageData('Echo datos recibidos en un arreglo',[$$api{data}]);
    } else {
        $api->MessageError('No se recibieron datos a procesar, áéíóúñÑ¡');
    }
}

sub put {
    if ($api->{data}) {
        $api->MessageData('Echo datos recibidos en data',$api->{data});
    } else {
        $api->MessageSuccess('No se recibieron datos a procesar, áéíóúñÑ¡');
    }
}