Script PHP à fichier unique qui ajoute une API REST à une base de données MySQL/MariaDB, PostgreSQL, SQL Server ou SQLite.
Comment : Téléchargez « api.php
» sur votre serveur Web, configurez-le pour vous connecter à votre base de données, disposez instantanément d'une API REST complète.
NB : Il s'agit de l'implémentation de référence TreeQL en PHP.
PHP 7.2 ou supérieur avec les pilotes PDO activés pour l'un de ces systèmes de base de données :
MySQL 5.7 / MariaDB 10.0 ou supérieur pour les fonctionnalités spatiales dans MySQL
PostgreSQL 9.5 ou supérieur avec PostGIS 2.2 ou supérieur pour les entités spatiales
SQL Server 2017 ou version ultérieure (2019 prend également en charge Linux)
SQLite 3.16 ou supérieur (fonctionnalités spatiales NON prises en charge)
Téléchargez le fichier " api.php
" de la dernière version :
https://github.com/mevdschee/php-crud-api/releases/latest ou directement depuis :
https://raw.githubusercontent.com/mevdschee/php-crud-api/main/api.php
Il s'agit d'une application à fichier unique ! Téléchargez " api.php
" quelque part et profitez-en !
Pour le développement local, vous pouvez exécuter le serveur Web intégré de PHP :
php -S localhost:8080
Testez le script en ouvrant l'URL suivante :
http://localhost:8080/api.php/records/posts/1
N'oubliez pas de modifier la configuration en bas du fichier.
Alternativement, vous pouvez intégrer ce projet dans le framework web de votre choix, voir :
API REST automatique pour Laravel
API REST automatique pour Symfony 4
API REST automatique pour SlimPHP 4
Dans ces intégrations, Composer est utilisé pour charger ce projet en tant que dépendance.
Pour les personnes n'utilisant pas composer, le fichier " api.include.php
" est fourni. Ce fichier contient tout ce qui vient de " api.php
" sauf la configuration de " src/index.php
" et peut être utilisé par la fonction " include " de PHP.
Editez les lignes suivantes en bas du fichier « api.php
» :
$config = new Config([ 'username' => 'xxx', 'password' => 'xxx', 'database' => 'xxx', ]);
Voici toutes les options de configuration et leur valeur par défaut entre parenthèses :
"pilote": mysql
, pgsql
, sqlsrv
ou sqlite
( mysql
)
"adresse" : nom d'hôte (ou nom de fichier) du serveur de base de données ( localhost
)
"port" : port TCP du serveur de base de données (par défaut, la valeur par défaut du pilote)
"username" : Nom d'utilisateur de l'utilisateur se connectant à la base de données (pas de valeur par défaut)
"password" : Mot de passe de l'utilisateur se connectant à la base de données (pas de défaut)
"database" : base de données à laquelle la connexion est effectuée (pas de valeur par défaut)
"command": Extra SQL pour initialiser la connexion à la base de données (aucun)
"tables" : liste de tables à publier séparées par des virgules (par défaut : "toutes")
"mapping" : liste de mappages table/colonne séparés par des virgules (pas de mappage)
"geometrySrid": SRID pris en compte lors de la conversion de WKT en géométrie ( 4326
)
"middlewares" : Liste des middlewares à charger ( cors
)
"controllers": Liste des contrôleurs à charger ( records,geojson,openapi,status
)
"customControllers" : Liste des contrôleurs personnalisés utilisateur à charger (pas de valeur par défaut)
"openApiBase" : informations OpenAPI ( {"info":{"title":"PHP-CRUD-API","version":"1.0.0"}}
)
"cacheType": TempFile
, Redis
, Memcache
, Memcached
ou NoCache
( TempFile
)
"cachePath" : chemin/adresse du cache (par défaut, le répertoire temporaire du système)
"cacheTime": Nombre de secondes pendant lesquelles le cache est valide ( 10
)
"jsonOptions": Options utilisées pour l'encodage JSON ( JSON_UNESCAPED_UNICODE
)
"debug" : Afficher les erreurs dans les en-têtes "X-Exception" ( false
)
"basePath" : chemin de base URI de l'API (déterminé à l'aide de PATH_INFO par défaut)
Toutes les options de configuration sont également disponibles sous forme de variables d'environnement. Écrivez l'option de configuration avec des majuscules, un préfixe "PHP_CRUD_API_" et des traits de soulignement pour les sauts de mots, par exemple :
PHP_CRUD_API_DRIVER=mysql
PHP_CRUD_API_ADDRESS=hôte local
PHP_CRUD_API_PORT=3306
PHP_CRUD_API_DATABASE=php-crud-api
PHP_CRUD_API_USERNAME=php-crud-api
PHP_CRUD_API_PASSWORD=php-crud-api
PHP_CRUD_API_DEBUG=1
Les variables d'environnement sont prioritaires sur la configuration PHP.
Ces limitations et contraintes s'appliquent :
Les clés primaires doivent être soit à incrémentation automatique (de 1 à 2 ^ 53), soit à UUID
Les clés primaires composites et étrangères composites ne sont pas prises en charge
Les écritures (transactions) complexes ne sont pas prises en charge
Les requêtes complexes appelant des fonctions (comme "concat" ou "sum") ne sont pas prises en charge
La base de données doit prendre en charge et définir les contraintes de clé étrangère
SQLite ne peut pas avoir de clés primaires à incrémentation automatique bigint tapées
SQLite ne prend pas en charge la modification des colonnes de table (structure)
Les fonctionnalités suivantes sont prises en charge :
Installation de Composer ou fichier PHP unique, facile à déployer.
Très peu de code, facile à adapter et à maintenir
Prend en charge les variables POST en entrée (x-www-form-urlencoded)
Prend en charge un objet JSON en entrée
Prend en charge un tableau JSON en entrée (insertion par lots)
Nettoyer et valider les entrées à l'aide de règles de type et de rappels
Système d'autorisation pour les bases de données, les tables, les colonnes et les enregistrements
Les configurations de bases de données multi-locataires, simples et multiples, sont prises en charge
Prise en charge CORS multi-domaines pour les requêtes inter-domaines
Prise en charge de la lecture des résultats joints à partir de plusieurs tables
Rechercher un support sur plusieurs critères
Pagination, tri, liste des N premiers et sélection de colonnes
Détection de relations avec résultats imbriqués (belongsTo, hasMany et HABTM)
Prise en charge de l'incrément atomique via PATCH (pour les compteurs)
Champs binaires pris en charge avec l'encodage base64
Champs et filtres spatiaux/SIG pris en charge avec WKT et GeoJSON
Mappage des noms de tables et de colonnes pour prendre en charge les systèmes existants
Générer de la documentation API à l'aide des outils OpenAPI
Authentification via clé API, jeton JWT ou nom d'utilisateur/mot de passe
Les paramètres de connexion à la base de données peuvent dépendre de l'authentification
Prise en charge de la lecture de la structure de la base de données en JSON
Prise en charge de la modification de la structure de la base de données à l'aide du point de terminaison REST
Un middleware améliorant la sécurité est inclus
Conforme aux normes : PSR-4, PSR-7, PSR-12, PSR-15 et PSR-17
Projets connexes :
Démarrage rapide PHP-CRUD-API : un fichier de composition Docker personnalisable et prêt à l'emploi comprenant PHP-CRUD-API.
Générateur de filtres PHP-CRUD-API : Une bibliothèque JavaScript créant des filtres PHP-CRUD-API à partir d'expressions.
JS-CRUD-API : Une bibliothèque client JavaScript pour l'API de PHP-CRUD-API
PHP-API-AUTH : script PHP à fichier unique qui est un fournisseur d'authentification pour PHP-CRUD-API
PHP-CRUD-UI : script PHP à fichier unique qui ajoute une interface utilisateur à un projet PHP-CRUD-API.
PHP-CRUD-ADMIN : script PHP à fichier unique qui ajoute une interface d'administration de base de données à un projet PHP-CRUD-API.
PHP-SP-API : script PHP à fichier unique qui ajoute une API REST à une base de données SQL.
dexie-mysql-sync : Synchronisation entre IndexedDB locale et la base de données MySQL.
ra-data-treeql : package NPM qui fournit un fournisseur de données pour React Admin.
scriptPilot/vueuse : Vue Composables en plus de VueUse.org (qui supporte PHP-CRUD-API).
scriptPilot/add-php-backend : ajoutez MySQL, phpMyAdmin et PHP-CRUD-API à votre environnement de développement.
VUE-CRUD-UI : script Vue.js à fichier unique qui ajoute une interface utilisateur à un projet PHP-CRUD-API.
Il existe également des ports de ce script dans :
Go-CRUD-API (travail en cours)
Java JDBC par Ivan Kolchagov (v1)
Java Spring Boot + jOOQ (v2 : travail en cours)
Il existe également des ports de validation de principe de ce script qui ne prennent en charge que les fonctionnalités de base de REST CRUD dans : PHP, Java, Go, C# .net core, Node.js et Python.
Vous pouvez installer toutes les dépendances de ce projet à l'aide de la commande suivante :
php install.php
Vous pouvez compiler tous les fichiers en un seul fichier " api.php
" en utilisant :
php build.php
Notez que vous n'utilisez pas la compilation lorsque vous intégrez ce projet dans un autre projet ou framework (utilisez plutôt Composer).
Vous pouvez accéder au code non compilé à l'URL :
http://localhost:8080/src/records/posts/1
Le code non compilé réside dans les répertoires " src
" et " vendor
". Le répertoire « vendor
» contient les dépendances.
Vous pouvez mettre à jour toutes les dépendances de ce projet à l'aide de la commande suivante :
php update.php
Ce script installera et exécutera Composer pour mettre à jour les dépendances.
NB : Le script de mise à jour corrigera les dépendances dans le répertoire des fournisseurs pour la compatibilité PHP 7.0.
TreeQL vous permet de créer un « arbre » d'objets JSON basé sur la structure (relations) de votre base de données SQL et votre requête.
Il est vaguement basé sur le standard REST et également inspiré de json:api.
L'exemple de table de publications ne contient que quelques champs :
posts ======= id title content created
Les opérations CRUD + List ci-dessous agissent sur cette table.
Si vous souhaitez créer un enregistrement, la demande peut être écrite au format URL comme :
POST /records/posts
Vous devez envoyer un corps contenant :
{ "title": "Black is the new red", "content": "This is the second post.", "created": "2018-03-06T21:34:01Z" }
Et il renverra la valeur de la clé primaire de l'enregistrement nouvellement créé :
2
Pour lire un enregistrement de cette table, la requête peut être écrite au format URL comme :
GET /records/posts/1
Où "1" est la valeur de la clé primaire de l'enregistrement que vous souhaitez lire. Il reviendra :
{ "id": 1 "title": "Hello world!", "content": "Welcome to the first post.", "created": "2018-03-05T20:12:56Z" }
Lors des opérations de lecture, vous pouvez appliquer des jointures.
Pour mettre à jour un enregistrement dans cette table, la requête peut être écrite au format URL comme :
PUT /records/posts/1
Où "1" est la valeur de la clé primaire de l'enregistrement que vous souhaitez mettre à jour. Envoyer en tant que corps :
{ "title": "Adjusted title!" }
Cela ajuste le titre du message. Et la valeur de retour est le nombre de lignes définies :
1
Si vous souhaitez supprimer un enregistrement de cette table, la demande peut être écrite au format URL comme :
DELETE /records/posts/1
Et il renverra le nombre de lignes supprimées :
1
Pour lister les enregistrements de cette table, la requête peut être écrite au format URL comme :
GET /records/posts
Il reviendra :
{ "records":[ { "id": 1, "title": "Hello world!", "content": "Welcome to the first post.", "created": "2018-03-05T20:12:56Z" } ] }
Sur les opérations de liste, vous pouvez appliquer des filtres et des jointures.
Les filtres fournissent une fonctionnalité de recherche, sur les appels de liste, à l'aide du paramètre "filter". Vous devez spécifier le nom de la colonne, une virgule, le type de correspondance, une autre virgule et la valeur sur laquelle vous souhaitez filtrer. Voici les types de correspondance pris en charge :
"cs": contient une chaîne (la chaîne contient une valeur)
"sw": commencer par (la chaîne commence par une valeur)
"ew": se termine par (la chaîne se termine par une valeur)
"eq": égal (la chaîne ou le nombre correspond exactement)
"lt" : inférieur à (le nombre est inférieur à la valeur)
"le" : inférieur ou égal (le nombre est inférieur ou égal à la valeur)
"ge" : supérieur ou égal (le nombre est supérieur ou égal à la valeur)
"gt" : supérieur à (le nombre est supérieur à la valeur)
"bt" : entre (le nombre est compris entre deux valeurs séparées par des virgules)
"in": in (le nombre ou la chaîne est dans une liste de valeurs séparées par des virgules)
"is": est nul (le champ contient la valeur "NULL")
Vous pouvez annuler tous les filtres en ajoutant un caractère "n", de sorte que "eq" devienne "neq". Voici des exemples d'utilisation de filtres :
GET /records/categories?filter=name,eq,Internet GET /records/categories?filter=name,sw,Inter GET /records/categories?filter=id,le,1 GET /records/categories?filter=id,ngt,1 GET /records/categories?filter=id,bt,0,1 GET /records/categories?filter=id,in,0,1
Sortir:
{ "records":[ { "id": 1 "name": "Internet" } ] }
Dans la section suivante, nous expliquons plus en détail comment appliquer plusieurs filtres sur un seul appel de liste.
Les filtres peuvent être appliqués en répétant le paramètre "filter" dans l'URL. Par exemple l'URL suivante :
GET /records/categories?filter=id,gt,1&filter=id,lt,3
demandera toutes les catégories "où id > 1 et id < 3". Si vous vouliez "where id = 2 ou id = 4", vous devez écrire :
GET /records/categories?filter1=id,eq,2&filter2=id,eq,4
Comme vous le voyez, nous avons ajouté un numéro au paramètre « filtre » pour indiquer que « OU » au lieu de « ET » doit être appliqué. Notez que vous pouvez également répéter « filter1 » et créer un « AND » dans un « OR ». Puisque vous pouvez également aller plus loin en ajoutant une lettre (af), vous pouvez créer presque n'importe quel arbre de conditions raisonnablement complexe.
NB : Vous ne pouvez filtrer que sur la table demandée (pas sur les tables incluses) et les filtres ne sont appliqués que sur les appels de liste.
Par défaut, toutes les colonnes sont sélectionnées. Avec le paramètre "include", vous pouvez sélectionner des colonnes spécifiques. Vous pouvez utiliser un point pour séparer le nom de la table du nom de la colonne. Plusieurs colonnes doivent être séparées par des virgules. Un astérisque ("*") peut être utilisé comme caractère générique pour indiquer "toutes les colonnes". Semblable à « inclure », vous pouvez utiliser le paramètre « exclure » pour supprimer certaines colonnes :
GET /records/categories/1?include=name GET /records/categories/1?include=categories.name GET /records/categories/1?exclude=categories.id
Sortir:
{ "name": "Internet" }
NB : les colonnes utilisées pour inclure les entités associées sont automatiquement ajoutées et ne peuvent pas être exclues de la sortie.
Avec le paramètre "order" vous pouvez trier. Par défaut, le tri est croissant, mais en spécifiant "desc", cela peut être inversé :
GET /records/categories?order=name,desc GET /records/categories?order=id,desc&order=name
Sortir:
{ "records":[ { "id": 3 "name": "Web development" }, { "id": 1 "name": "Internet" } ] }
NB : Vous pouvez trier sur plusieurs champs en utilisant plusieurs paramètres "ordre". Vous ne pouvez pas commander sur les colonnes "jointes".
Le paramètre "size" limite le nombre d'enregistrements renvoyés. Ceci peut être utilisé pour les N premières listes avec le paramètre "order" (utilisez l'ordre décroissant).
GET /records/categories?order=id,desc&size=1
Sortir:
{ "records":[ { "id": 3 "name": "Web development" } ] }
NB : Si vous souhaitez également connaître le nombre total d'enregistrements vous pouvez utiliser le paramètre "page".
Le paramètre "page" contient la page demandée. La taille de page par défaut est de 20, mais peut être ajustée (par exemple jusqu'à 50).
GET /records/categories?order=id&page=1 GET /records/categories?order=id&page=1,50
Sortir:
{ "records":[ { "id": 1 "name": "Internet" }, { "id": 3 "name": "Web development" } ], "results": 2 }
L'élément "results" contient le nombre total d'enregistrements dans la table, qui serait renvoyé si aucune pagination n'était utilisée.
NB : Les pages non ordonnées ne pouvant pas être paginées, les pages seront ordonnées par clé primaire.
Disons que vous disposez d'un tableau de publications contenant des commentaires (faits par les utilisateurs) et que les publications peuvent avoir des balises.
posts comments users post_tags tags ======= ======== ======= ========= ======= id id id id id title post_id username post_id name content user_id phone tag_id created message
Lorsque vous souhaitez lister les publications avec leurs commentaires, utilisateurs et tags, vous pouvez demander deux chemins « arborescence » :
posts -> comments -> users posts -> post_tags -> tags
Ces chemins ont la même racine et cette requête peut être écrite au format URL comme suit :
GET /records/posts?join=comments,users&join=tags
Ici, vous êtes autorisé à laisser de côté le tableau intermédiaire qui lie les publications aux balises. Dans cet exemple, vous voyez les trois types de relations de table (hasMany, appartientTo et hasAndBelongsToMany) en vigueur :
"post" contient de nombreux "commentaires"
"commentaire" appartient à "utilisateur"
"post" a et appartient à de nombreuses "tags"
Cela peut conduire aux données JSON suivantes :
{ "records":[ { "id": 1, "title": "Hello world!", "content": "Welcome to the first post.", "created": "2018-03-05T20:12:56Z", "comments": [ { id: 1, post_id: 1, user_id: { id: 1, username: "mevdschee", phone: null, }, message: "Hi!" }, { id: 2, post_id: 1, user_id: { id: 1, username: "mevdschee", phone: null, }, message: "Hi again!" } ], "tags": [] }, { "id": 2, "title": "Black is the new red", "content": "This is the second post.", "created": "2018-03-06T21:34:01Z", "comments": [], "tags": [ { id: 1, message: "Funny" }, { id: 2, message: "Informational" } ] } ] }
Vous voyez que les relations « belongsTo » sont détectées et la valeur de la clé étrangère est remplacée par l'objet référencé. Dans le cas de "hasMany" et "hasAndBelongsToMany", le nom de la table est utilisé comme une nouvelle propriété sur l'objet.
Lorsque vous souhaitez créer, lire, mettre à jour ou supprimer, vous pouvez spécifier plusieurs valeurs de clé primaire dans l'URL. Vous devez également envoyer un tableau au lieu d'un objet dans le corps de la demande pour la création et la mise à jour.
Pour lire un enregistrement de cette table, la requête peut être écrite au format URL comme :
GET /records/posts/1,2
Le résultat peut être :
[ { "id": 1, "title": "Hello world!", "content": "Welcome to the first post.", "created": "2018-03-05T20:12:56Z" }, { "id": 2, "title": "Black is the new red", "content": "This is the second post.", "created": "2018-03-06T21:34:01Z" } ]
De même lorsque vous souhaitez faire une mise à jour batch la requête au format URL s'écrit ainsi :
PUT /records/posts/1,2
Où « 1 » et « 2 » sont les valeurs des clés primaires des enregistrements que vous souhaitez mettre à jour. Le corps doit contenir le même nombre d'objets qu'il y a de clés primaires dans l'URL :
[ { "title": "Adjusted title for ID 1" }, { "title": "Adjusted title for ID 2" } ]
Cela ajuste les titres des articles. Et les valeurs de retour sont le nombre de lignes définies :
[1,1]
Ce qui signifie qu'il y a eu deux opérations de mise à jour et que chacune d'elles avait défini une ligne. Les opérations par lots utilisent des transactions de base de données, elles réussissent donc toutes ou échouent (celles qui réussissent sont annulées). S'ils échouent, le corps contiendra la liste des documents d'erreur. Dans la réponse suivante, la première opération a réussi et la deuxième opération du lot a échoué en raison d'une violation d'intégrité :
[ { "code": 0, "message": "Success" }, { "code": 1010, "message": "Data integrity violation" } ]
Le code d'état de la réponse sera toujours 424 (dépendance en échec) en cas d'échec de l'une des opérations par lots.
Pour insérer plusieurs enregistrements dans cette table, la requête peut être écrite au format URL comme :
POST /records/posts
Le corps doit contenir un tableau d'enregistrements à insérer :
[ { "title": "Hello world!", "content": "Welcome to the first post.", "created": "2018-03-05T20:12:56Z" }, { "title": "Black is the new red", "content": "This is the second post.", "created": "2018-03-06T21:34:01Z" } ]
La valeur de retour est également un tableau contenant les clés primaires des enregistrements nouvellement insérés :
[1,2]
Notez que l’opération par lots pour DELETE suit le même modèle que PUT, mais sans corps.
Pour la prise en charge spatiale, il existe un ensemble supplémentaire de filtres qui peuvent être appliqués aux colonnes géométriques et qui commencent par un « s » :
"sco": spatial contient (la géométrie en contient une autre)
"scr" : croisements spatiaux (la géométrie en croise une autre)
"sdi" : spatial disjoint (la géométrie est disjointe d'une autre)
"seq" : spatial égal (la géométrie est égale à une autre)
"péché": l'espace se croise (la géométrie en croise une autre)
"sov": chevauchements spatiaux (la géométrie en chevauche une autre)
"sto" : touches spatiales (la géométrie en touche une autre)
"swi": spatial à l'intérieur (la géométrie est à l'intérieur d'une autre)
"sic" : le spatial est fermé (la géométrie est fermée et simple)
"sis": le spatial est simple (la géométrie est simple)
"siv": spatial est valide (la géométrie est valide)
Ces filtres sont basés sur les normes OGC, tout comme la spécification WKT dans laquelle les colonnes géométriques sont représentées. Notez que le SRID supposé lors de la conversion de WKT en géométrie est spécifié par la variable de configuration geometrySrid
et est par défaut 4326 (WGS 84).
Le support GeoJSON est une vue en lecture seule sur les tables et enregistrements au format GeoJSON. Ces demandes sont prises en charge :
method path - operation - description ---------------------------------------------------------------------------------------- GET /geojson/{table} - list - lists records as a GeoJSON FeatureCollection GET /geojson/{table}/{id} - read - reads a record by primary key as a GeoJSON Feature
Le point de terminaison " /geojson
" utilise le point de terminaison " /records
" en interne et hérite de toutes les fonctionnalités, telles que les jointures et les filtres. Il prend également en charge un paramètre "géométrie" pour indiquer le nom de la colonne de géométrie au cas où la table en aurait plusieurs. Pour les vues cartographiques, il prend en charge le paramètre "bbox" dans lequel vous pouvez spécifier les coordonnées supérieure gauche et inférieure droite (séparées par des virgules). Les types de géométrie suivants sont pris en charge par l'implémentation GeoJSON :
Indiquer
MultiPoint
Chaîne de ligne
Chaîne MultiLigne
Polygone
MultiPolygone
La fonctionnalité GeoJSON est activée par défaut, mais peut être désactivée à l'aide de la configuration « contrôleurs ».
Pour prendre en charge la création d'une API pour (une partie de) un système existant (tel que Wordpress), vous souhaiterez peut-être mapper les noms de table et de colonne, car ils ne peuvent pas être améliorés sans modifier le logiciel, tandis que les noms peuvent nécessiter une certaine amélioration pour des raisons de cohérence. La configuration vous permet de renommer les tables et les colonnes avec une liste de mappages séparés par des virgules et divisés par un signe égal, comme ceci :
'mapping' => 'wp_posts=posts,wp_posts.ID=posts.id',
Cet exemple spécifique exposera la table " wp_posts
" à un point final " posts
" (au lieu de " wp_posts
") et la colonne " ID
" dans cette table en tant que propriété " id
" (en minuscules au lieu de majuscules).
NB : Étant donné que ces deux mappages se chevauchent, le premier mappage (moins spécifique) peut être omis.
Vous pouvez activer le middleware suivant à l'aide du paramètre de configuration « middlewares » :
"firewall": Limiter l'accès à des adresses IP spécifiques
"sslRedirect" : Forcer la connexion via HTTPS au lieu de HTTP
"cors" : Prise en charge des requêtes CORS (activée par défaut)
"xsrf" : bloque les attaques XSRF à l'aide de la méthode "Double Submit Cookie"
"ajaxOnly" : restreindre les requêtes non-AJAX pour empêcher les attaques XSRF
"apiKeyAuth" : prise en charge de "l'authentification par clé API"
"apiKeyDbAuth" : prise en charge de "l'authentification par clé API par base de données"
"dbAuth" : prise en charge de "l'authentification de base de données"
"wpAuth" : prise en charge de "l'authentification Wordpress"
"jwtAuth" : prise en charge de "l'authentification JWT"
"basicAuth" : prise en charge de "l'authentification de base"
"reconnect" : Reconnectez-vous à la base de données avec des paramètres différents
"authorization" : Restreindre l'accès à certaines tables ou colonnes
"validation" : renvoie les erreurs de validation d'entrée pour les règles personnalisées et les règles de type par défaut
"ipAddress" : Remplissez un champ protégé avec l'adresse IP lors de la création
"sanitation" : appliquer l'assainissement des entrées lors de la création et de la mise à jour
"multiTenancy" : restreint l'accès des locataires dans un scénario multi-tenant
"pageLimits" : restreint les opérations de liste pour empêcher le scraping de la base de données
"joinLimits" : restreint les paramètres de jointure pour empêcher le scraping de la base de données
"textSearch" : Rechercher dans tous les champs de texte avec un simple paramètre
« personnalisation » : fournit des gestionnaires pour la personnalisation des demandes et des réponses
"json" : prise en charge de la lecture/écriture des chaînes JSON en tant qu'objets/tableaux JSON
"xml" : traduit toutes les entrées et sorties de JSON en XML
Le paramètre de configuration « middlewares » est une liste de middlewares activés, séparés par des virgules. Vous pouvez ajuster le comportement du middleware à l'aide de paramètres de configuration spécifiques au middleware :
"firewall.reverseProxy" : défini sur "true" lorsqu'un proxy inverse est utilisé ("")
"firewall.allowedIpAddresses" : Liste des adresses IP autorisées à se connecter ("")
"cors.allowedOrigins" : Les origines autorisées dans les en-têtes CORS ("*")
"cors.allowHeaders" : Les en-têtes autorisés dans la requête CORS ("Content-Type, X-XSRF-TOKEN, X-Authorization")
"cors.allowMethods" : Les méthodes autorisées dans la requête CORS ("OPTIONS, GET, PUT, POST, DELETE, PATCH")
"cors.allowCredentials" : pour autoriser les informations d'identification dans la requête CORS ("true")
"cors.exposeHeaders": en-têtes de liste blanche auxquels les navigateurs sont autorisés à accéder ("")
"cors.maxAge" : durée de validité de l'octroi CORS en secondes ("1728000")
"xsrf.excludeMethods" : Les méthodes qui ne nécessitent pas de protection XSRF ("OPTIONS,GET")
"xsrf.cookieName" : Le nom du cookie de protection XSRF ("XSRF-TOKEN")
"xsrf.headerName" : Le nom de l'en-tête de protection XSRF ("X-XSRF-TOKEN")
"ajaxOnly.excludeMethods" : Les méthodes qui ne nécessitent pas AJAX ("OPTIONS,GET")
"ajaxOnly.headerName": Le nom de l'en-tête requis ("X-Requested-With")
"ajaxOnly.headerValue" : La valeur de l'en-tête requis ("XMLHttpRequest")
"apiKeyAuth.mode" : défini sur "facultatif" si vous souhaitez autoriser l'accès anonyme ("obligatoire")
"apiKeyAuth.header" : Le nom de l'en-tête de la clé API ("X-API-Key")
"apiKeyAuth.keys" : Liste des clés API valides ("")
"apiKeyDbAuth.mode" : défini sur "facultatif" si vous souhaitez autoriser l'accès anonyme ("obligatoire")
"apiKeyDbAuth.header" : Le nom de l'en-tête de la clé API ("X-API-Key")
"apiKeyDbAuth.usersTable": La table utilisée pour stocker les utilisateurs dans ("users")
"apiKeyDbAuth.apiKeyColumn" : colonne de la table des utilisateurs qui contient la clé API ("api_key")
"dbAuth.mode" : défini sur "facultatif" si vous souhaitez autoriser l'accès anonyme ("obligatoire")
"dbAuth.usersTable": La table utilisée pour stocker les utilisateurs dans ("users")
"dbAuth.loginTable": La table ou la vue utilisée pour récupérer les informations des utilisateurs pour la connexion ("utilisateurs")
"dbAuth.usernameColumn": La colonne de la table des utilisateurs qui contient les noms d'utilisateur ("username")
"dbAuth.passwordColumn" : la colonne de la table des utilisateurs qui contient les mots de passe ("password")
"dbAuth.returnedColumns" : les colonnes renvoyées lors d'une connexion réussie, vides signifie "toutes" ("")
"dbAuth.usernameFormField": Le nom du champ de formulaire contenant le nom d'utilisateur ("username")
"dbAuth.passwordFormField" : Le nom du champ du formulaire qui contient le mot de passe ("password")
"dbAuth.newPasswordFormField" : Le nom du champ du formulaire qui contient le nouveau mot de passe ("newPassword")
"dbAuth.registerUser": données utilisateur JSON (ou "1") au cas où vous souhaiteriez activer le point de terminaison /register ("")
"dbAuth.loginAfterRegistration": 1 ou zéro si les utilisateurs enregistrés doivent être connectés après l'enregistrement ("")
"dbAuth.passwordLength": Longueur minimale que doit avoir le mot de passe ("12")
"dbAuth.sessionName": Le nom de la session PHP démarrée ("")
"wpAuth.mode" : définissez sur "facultatif" si vous souhaitez autoriser l'accès anonyme ("obligatoire")
"wpAuth.wpDirectory": Le dossier/chemin où se trouve l'installation de Wordpress ("".")
"wpAuth.usernameFormField" : Le nom du champ du formulaire qui contient le nom d'utilisateur ("username")
"wpAuth.passwordFormField" : Le nom du champ du formulaire qui contient le mot de passe ("password")
"jwtAuth.mode" : défini sur "facultatif" si vous souhaitez autoriser l'accès anonyme ("obligatoire")
"jwtAuth.header" : Nom de l'en-tête contenant le token JWT ("X-Authorization")
"jwtAuth.leeway" : nombre acceptable de secondes de décalage d'horloge ("5")
"jwtAuth.ttl" : le nombre de secondes pendant lesquelles le jeton est valide ("30")
"jwtAuth.secrets" : le(s) secret(s) partagé(s) utilisé(s) pour signer le jeton JWT avec ("")
"jwtAuth.algorithms" : Les algorithmes autorisés, vide signifie "tous" ("")
"jwtAuth.audiences" : les audiences autorisées, vides signifie « toutes » ("")
"jwtAuth.issuers" : Les émetteurs autorisés, vide signifie "tous" ("")
"jwtAuth.sessionName": Le nom de la session PHP démarrée ("")
"basicAuth.mode" : définissez sur "facultatif" si vous souhaitez autoriser l'accès anonyme ("obligatoire")
"basicAuth.realm" : texte à afficher lors de l'affichage de la connexion ("Nom d'utilisateur et mot de passe requis")
"basicAuth.passwordFile" : Le fichier à lire pour les combinaisons nom d'utilisateur/mot de passe (".htpasswd")
"basicAuth.sessionName": Le nom de la session PHP démarrée ("")
"reconnect.driverHandler": Gestionnaire pour implémenter la récupération du pilote de base de données ("")
"reconnect.addressHandler": Gestionnaire pour implémenter la récupération de l'adresse de la base de données ("")
"reconnect.portHandler": Gestionnaire pour implémenter la récupération du port de la base de données ("")
"reconnect.databaseHandler": Gestionnaire pour implémenter la récupération du nom de la base de données ("")
"reconnect.tablesHandler": Gestionnaire pour implémenter la récupération des noms de tables ("")
"reconnect.mappingHandler": Gestionnaire pour implémenter la récupération du mappage de nom ("")
"reconnect.usernameHandler": Gestionnaire pour implémenter la récupération du nom d'utilisateur de la base de données ("")
"reconnect.passwordHandler": Gestionnaire pour implémenter la récupération du mot de passe de la base de données ("")
"authorization.tableHandler": Gestionnaire pour implémenter les règles d'autorisation de table ("")
"authorization.columnHandler": Gestionnaire pour implémenter les règles d'autorisation de colonne ("")
"authorization.pathHandler": Gestionnaire pour implémenter les règles d'autorisation de chemin ("")
"authorization.recordHandler" : gestionnaire pour implémenter les règles de filtre d'autorisation d'enregistrement ("")
"validation.handler": Gestionnaire pour implémenter des règles de validation pour les valeurs d'entrée ("")
"validation.types": Types pour lesquels activer la validation de type, vide signifie "aucun" ("tous")
"validation.tables": Tables pour lesquelles activer la validation de type, vide signifie "aucune" ("toutes")
"ipAddress.tables": Tables dans lesquelles rechercher les colonnes à remplacer par l'adresse IP ("")
"ipAddress.columns": Colonnes à protéger et à remplacer par l'adresse IP lors de la création ("")
"sanitation.handler": Gestionnaire pour implémenter des règles d'assainissement pour les valeurs d'entrée ("")
"sanitation.types": Types pour lesquels activer l'assainissement de type, vide signifie "aucun" ("tous")
"sanitation.tables": Tables pour lesquelles activer le type d'assainissement, vide signifie "aucun" ("tous")
"multiTenancy.handler" : gestionnaire pour implémenter des règles multi-tenant simples ("")
"pageLimits.pages" : le nombre maximum de pages autorisé par une opération de liste ("100")
"pageLimits.records" : le nombre maximum d'enregistrements renvoyés par une opération de liste ("1000")
"joinLimits.degree" : la profondeur (longueur) maximale autorisée dans un chemin de jointure ("3")
"joinLimits.tables": Le nombre maximum de tables que vous êtes autorisé à rejoindre ("10")
"joinLimits.records" : le nombre maximum d'enregistrements renvoyés pour une entité jointe ("1 000")
"textSearch.parameter" : Le nom du paramètre utilisé pour le terme de recherche ("search")
"customization.beforeHandler" : gestionnaire pour implémenter la personnalisation des requêtes ("")
"customization.afterHandler" : gestionnaire pour implémenter la personnalisation de la réponse ("")
"json.controllers" : contrôleurs pour traiter les chaînes JSON ("records,geojson")
"json.tables": Tables pour traiter les chaînes JSON pour ("toutes")
"json.columns" : colonnes pour traiter les chaînes JSON ("toutes")
"xml.types" : types JSON à ajouter à l'attribut de type XML ("null,array")
Si vous ne spécifiez pas ces paramètres dans la configuration, alors les valeurs par défaut (entre parenthèses) sont utilisées.
Dans les sections ci-dessous, vous trouverez plus d'informations sur le middleware intégré.
Actuellement, cinq types d'authentification sont pris en charge. Ils stockent tous l'utilisateur authentifié dans le super global $_SESSION
. Cette variable peut être utilisée dans les gestionnaires d'autorisation pour décider si quelqu'un doit ou non avoir un accès en lecture ou en écriture à certaines tables, colonnes ou enregistrements. La présentation suivante montre les types de middleware d'authentification que vous pouvez activer.
Nom | Intergiciel | Authentifié via | Les utilisateurs sont stockés dans | Variable de session |
---|---|---|---|---|
Clé API | apiKeyAuth | En-tête 'X-API-Key' | configuration | $_SESSION['apiKey'] |
Base de données de clé API | apiKeyDbAuth | En-tête 'X-API-Key' | table de base de données | $_SESSION['apiUser'] |
Base de données | dbAuth | Point de terminaison '/login' | table de base de données | $_SESSION['user'] |
Basique | baseAuth | En-tête « Autorisation » | Fichier '.htpasswd' | $_SESSION['username'] |
JWT | jwtAuth | En-tête « Autorisation » | fournisseur d'identité | $_SESSION['claims'] |
Vous trouverez ci-dessous plus d'informations sur chacun des types d'authentification.
L'authentification par clé API fonctionne en envoyant une clé API dans un en-tête de requête. Le nom de l'en-tête est par défaut "X-API-Key" et peut être configuré à l'aide du paramètre de configuration "apiKeyAuth.header". Les clés API valides doivent être configurées à l'aide du paramètre de configuration « apiKeyAuth.keys » (liste séparée par des virgules).
X-API-Key: 02c042aa-c3c2-4d11-9dae-1a6e230ea95e
La clé API authentifiée sera stockée dans la variable $_SESSION['apiKey']
.
Notez que l'authentification par clé API ne nécessite ni n'utilise de cookies de session.
L'authentification de la base de données de clés API fonctionne en envoyant une clé API dans un en-tête de requête "X-API-Key" (le nom est configurable). Les clés API valides sont lues dans la base de données à partir de la colonne "api_key" de la table "users" (les deux noms sont configurables).
X-API-Key: 02c042aa-c3c2-4d11-9dae-1a6e230ea95e
L'utilisateur authentifié (avec toutes ses propriétés) sera stocké dans la variable $_SESSION['apiUser']
.
Notez que l'authentification de la base de données de clés API ne nécessite ni n'utilise de cookies de session.
Le middleware d'authentification de base de données définit cinq nouvelles routes :
method path - parameters - description --------------------------------------------------------------------------------------------------- GET /me - - returns the user that is currently logged in POST /register - username, password - adds a user with given username and password POST /login - username, password - logs a user in by username and password POST /password - username, password, newPassword - updates the password of the logged in user POST /logout - - logs out the currently logged in user
Un utilisateur peut être connecté en envoyant son nom d'utilisateur et son mot de passe au point de terminaison de connexion (au format JSON). L'utilisateur authentifié (avec toutes ses propriétés) sera stocké dans la variable $_SESSION['user']
. L'utilisateur peut être déconnecté en envoyant une requête POST avec un corps vide au point de terminaison de déconnexion. Les mots de passe sont stockés sous forme de hachages dans la colonne des mots de passe de la table des utilisateurs. Vous pouvez enregistrer un nouvel utilisateur à l'aide du point de terminaison de registre, mais cette fonctionnalité doit être activée à l'aide du paramètre de configuration « dbAuth.registerUser ».
Il est IMPORTANT de restreindre l'accès à la table des utilisateurs à l'aide du middleware 'autorisation', sinon tous les utilisateurs peuvent librement ajouter, modifier ou supprimer n'importe quel compte ! La configuration minimale est présentée ci-dessous :
'middlewares' => 'dbAuth,authorization', 'authorization.tableHandler' => function ($operation, $tableName) { return $tableName != 'users'; },
Notez que ce middleware utilise des cookies de session et stocke l'état de connexion sur le serveur.
Connectez-vous en utilisant des vues avec une table jointe
Pour les opérations de connexion, il est possible d'utiliser une vue comme userTable. Une telle vue peut renvoyer un résultat filtré de la table des utilisateurs, par exemple où active = true ou elle peut également renvoyer un résultat sur plusieurs tables via une jointure de tables. Au minimum, la vue doit inclure le nom d'utilisateur et le mot de passe ainsi qu'un champ nommé id .
Cependant, les vues avec des tables jointes ne peuvent pas être insérées (voir problème 907). Pour contourner le problème, utilisez la propriété loginTable pour définir une table de référence différente pour la connexion. La table usersTable sera toujours définie sur la table des utilisateurs normale et insérable.
Le middleware d'authentification Wordpress définit trois routes :
method path - parameters - description --------------------------------------------------------------------------------------------------- GET /me - - returns the user that is currently logged in POST /login - username, password - logs a user in by username and password POST /logout - - logs out the currently logged in user
Un utilisateur peut être connecté en envoyant son nom d'utilisateur et son mot de passe au point de terminaison de connexion (au format JSON). L'utilisateur peut être déconnecté en envoyant une requête POST avec un corps vide au point de terminaison de déconnexion. Vous devez spécifier le répertoire d'installation de Wordpress à l'aide du paramètre de configuration "wpAuth.wpDirectory". Le middleware appelle "wp-load.php" cela vous permet d'utiliser des fonctions Wordpress dans le middleware d'autorisation, comme :
wp_get_current_user()
is_user_logged_in()
est_super_admin()
user_can(wp_get_current_user(),'edit_posts');
Notez que la variable $_SESSION
n'est pas utilisée par ce middleware.
Le type Basic prend en charge un fichier (par défaut '.htpasswd') qui contient les utilisateurs et leurs mots de passe (hachés) séparés par deux points (':'). Lorsque les mots de passe sont saisis en texte brut, ils seront automatiquement hachés. Le nom d'utilisateur authentifié sera stocké dans la variable $_SESSION['username']
. Vous devez envoyer un en-tête « Autorisation » contenant une version codée en URL base64 de votre nom d'utilisateur et de votre mot de passe séparés par deux points, après le mot « Basique ».
Authorization: Basic dXNlcm5hbWUxOnBhc3N3b3JkMQ
Cet exemple envoie la chaîne « username1:password1 ».
Le type JWT nécessite qu'un autre serveur (SSO/Identity) signe un jeton contenant des revendications. Les deux serveurs partagent un secret afin qu'ils puissent signer ou vérifier que la signature est valide. Les réclamations sont stockées dans la variable $_SESSION['claims']
. Vous devez envoyer un en-tête "X-Authorization" contenant un en-tête, un corps et une signature de jeton codés en URL base64 et séparés par des points après le mot "Bearer" (en savoir plus sur JWT ici). La norme indique que vous devez utiliser l'en-tête "Authorization", mais cela pose problème dans Apache et PHP.
X-Authorization: Bearer eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6IjE1MzgyMDc2MDUiLCJleHAiOjE1MzgyMDc2MzV9.Z5px_GT15TRKhJCTHhDt5Z6K6LRDSFnLj8U5ok9l7gw
Cet exemple envoie les revendications signées :
{ "sub": "1234567890", "name": "John Doe", "admin": true, "iat": "1538207605", "exp": 1538207635 }
NB : L'implémentation JWT ne prend en charge que les algorithmes basés sur RSA et HMAC.