API REST¶
Resumen¶
Esta página explica cómo ofrecer una API REST desde una app con ApiController y el atributo #[CORS], cómo versionarla y modificar las cabeceras CORS, y compara los controladores simples con los de OCS, incluidas las opciones históricas. Está dirigida a quienes desarrollan apps.
Fuente: documentación de Nextcloud, «developer_manual/digging_deeper/rest_apis», versión 3ad9158, licencia CC BY 3.0; traducida y adaptada para APS Conecta Gestión.
Ofrecer una API RESTful no es distinto de crear una ruta y controladores para la interfaz web.
Sin embargo, se recomienda heredar de ApiController y agregar el atributo #[CORS] a los métodos para que las aplicaciones web también puedan acceder a la API.
<?php
namespace OCA\MyApp\Controller;
use OCP\AppFramework\ApiController;
use OCP\AppFramework\Http\Attribute\CORS;
use OCP\IRequest;
class AuthorApiController extends ApiController {
public function __construct($appName, IRequest $request) {
parent::__construct($appName, $request);
}
#[CORS]
public function index() {
}
}
CORS también necesita una URL aparte para la solicitud de verificación previa OPTIONS, que se puede agregar fácilmente añadiendo la siguiente ruta:
<?php
// appinfo/routes.php
array(
'name' => 'author_api#preflighted_cors',
'url' => '/api/1.0/{path}',
'verb' => 'OPTIONS',
'requirements' => array('path' => '.+')
)
Hay que tener en cuenta que es probable que varias apps dependan de la interfaz de la API una vez publicada, y que reaccionarán a distinta velocidad a los cambios implementados en la API. Por eso se recomienda versionar la API en la URL para no romper las apps existentes cuando se introduzcan cambios incompatibles con versiones anteriores:
/index.php/apps/myapp/api/1.0/resource
Modificar las cabeceras CORS¶
De forma predeterminada, se usarán los siguientes valores para la solicitud OPTIONS de verificación previa:
Access-Control-Allow-Methods: 'PUT, POST, GET, DELETE, PATCH'
Access-Control-Allow-Headers: 'Authorization, Content-Type, Accept'
Access-Control-Max-Age: 1728000
Para agregar un método o una cabecera adicional, o para permitir menos cabeceras, basta con pasar valores adicionales al constructor padre:
<?php
namespace OCA\MyApp\Controller;
use \OCP\AppFramework\ApiController;
use \OCP\IRequest;
class AuthorApiController extends ApiController {
public function __construct($appName, IRequest $request) {
parent::__construct(
$appName,
$request,
'PUT, POST, GET, DELETE, PATCH',
'Authorization, Content-Type, Accept',
1728000);
}
}
Relación entre REST y OCS¶
Existe una relación estrecha entre las API REST y OCS. Ambas proporcionan una forma de transmitir datos entre el backend de la app en el servidor APS Conecta Gestión y algún frontend. Explícitamente, esto no trata de las respuestas de plantillas HTML.
Métodos actuales y comparación¶
Las siguientes combinaciones de atributos pueden ser relevantes para distintos escenarios:
Ruta de frontend simple: clase
ControllerRuta OCS: clase
OCSControllerRuta OCS con CORS activado: clase
OCSControllery atributo#[CORS]en el método
Advertencia
Agregar el atributo #[NoCSRFRequired] supone un riesgo de seguridad.
No se debe agregar a los métodos del controlador salvo que se comprendan las implicaciones y se tenga la certeza de que el atributo es absolutamente necesario.
Normalmente, en su lugar se puede usar la cabecera OCS-APIRequest en las solicitudes de datos, a fin de satisfacer las comprobaciones CSRF de las solicitudes a la API.
Advertencia
Agregar solo el atributo #[CORS] no basta para permitir el acceso mediante CORS con rutas de frontend simples.
Sin más medidas, el comprobador de CSRF fallaría.
Por eso, activar CORS en controladores simples se desaconseja de forma general y rotunda.
Habría que desactivar las comprobaciones CSRF (un riesgo de seguridad más), o usar la cabecera OCP-APIRequest o enviar un token CSRF para superar las comprobaciones.
Esto último requiere código JS específico en la página que importa.
Hay distintas formas en que los clientes pueden interactuar con las API. Estas formas dependen de la configuración de la API (lo que se permite) y de la ruta a la que finalmente se haga la solicitud.
Acceso desde el frontend web significa que el usuario accede al frontend web de APS Conecta Gestión con un navegador web.
Acceso desde fuera del navegador se da cuando el usuario accede al recurso o a la página usando algo que no es un navegador web, como una app de Android o un comando curl.
Acceso desde un sitio web externo significa que el usuario navega por algún sitio web de terceros y en él aparecen datos del servidor APS Conecta Gestión. Para poder hacerlo, el otro sitio web tiene que incrustar/cargar/usar imágenes, datos JSON u otros recursos desde una URL que apunta al servidor APS Conecta Gestión.
Consejo
Lo expuesto aquí se refiere solo a las solicitudes de datos. Si se piensa en métodos de controlador que sirven plantillas (HTML), desactivar CSRF se considera aceptable.
Descripción |
Clase |
Clase |
Clase |
|---|---|---|---|
Prefijo de URL (relativo al servidor) |
|
|
|
Acceso desde el frontend web |
sí |
sí |
sí |
Acceso desde fuera del navegador |
parcial [1] |
sí |
sí |
Acceso desde un sitio web externo |
no |
no |
sí |
Datos encapsulados |
no |
sí (JSON o XML) |
sí (JSON o XML) |
Los métodos de las clases Controller pueden devolver objetos DataResponse, de forma similar a los métodos de la clase OCSController.
En los métodos de una clase Controller, los datos de esta respuesta se envían, p. ej., como JSON, tal como se proporcionan.
Básicamente, la salida es muy similar a lo que haría json_encode.
En cambio, el OCSController encapsula los datos en una envoltura externa que proporciona algo más de (meta)información.
Por ejemplo, en el nivel superior se transmite un código de estado (similar al código de estado HTTP).
Los datos reales se transmiten en la propiedad data.
Como regla general, se puede concluir que OCS ofrece una buena forma de cubrir la mayoría de los casos de uso, incluidas comprobaciones de seguridad suficientes. La única excepción es cuando se quiere ofrecer una API para uso externo en la que hay que cumplir un esquema de API definido externamente. En ese caso, la encapsulación que introduce OCS y las comprobaciones CSRF pueden ser un obstáculo.
Opciones históricas¶
Obsoleto desde la versión 30: La información de esta sección es principalmente de referencia. No usar estos enfoques en código nuevo.
Antes de APS Conecta Gestión 30, los métodos de las clases Controller simples no respetaban la cabecera OCS-APIRequest.
Por eso, para dar acceso a apps externas a este tipo de métodos de controlador, era necesario usar el atributo #[NoCSRFRequired] (o la anotación @NoCSRFRequired correspondiente).
Las siguientes combinaciones de atributos eran relevantes para distintos escenarios:
Ruta de frontend simple: clase
ControllerFrontend simple con las comprobaciones CSRF desactivadas: clase
Controllery atributo#[NoCSRFRequired]en el métodoRuta de frontend simple con CORS activado: clase
Controllery atributos#[CORS]y#[NoCSRFRequired]en la rutaRuta OCS: clase
OCSControllerRuta OCS con CORS activado: clase
OCSControllery atributo#[CORS]en el método
Consejo
Los dos escenarios en los que interviene el OCSController no han cambiado y, por tanto, la documentación actual indicada más arriba sigue siendo válida.
Por eso, estas opciones no se vuelven a considerar aquí, por simplicidad y para que la visión general sea más nítida.
Las advertencias sobre no usar NoCSRFRequired y CORS mencionadas en la sección de métodos actuales también son válidas aquí.
Descripción |
Clase |
Clase |
Clase |
|---|---|---|---|
Prefijo de URL (relativo al servidor) |
|
|
|
Acceso desde el frontend web |
sí |
sí (riesgo de CSRF) |
sí (riesgo de CSRF) |
Acceso desde fuera del navegador |
no |
sí |
sí |
Acceso desde un sitio web externo |
no |
no |
sí |
Datos encapsulados |
no |
no |
no |