diff --git a/docs/img/api_key_authorize_1.png b/docs/img/api_key_authorize_1.png new file mode 100644 index 00000000..b01d2e66 Binary files /dev/null and b/docs/img/api_key_authorize_1.png differ diff --git a/docs/img/api_key_authorize_2.png b/docs/img/api_key_authorize_2.png new file mode 100644 index 00000000..9d562328 Binary files /dev/null and b/docs/img/api_key_authorize_2.png differ diff --git a/docs/tutorial/connect-api.md b/docs/tutorial/connect-api.md new file mode 100644 index 00000000..72c01a85 --- /dev/null +++ b/docs/tutorial/connect-api.md @@ -0,0 +1,215 @@ +La connexion à l'API du site AE peut se faire par deux moyens : + +- par le cookie de session du site ; si vous accédez à l'API depuis le sith + en étant connecté, cette méthode fonctionne par défaut +- par clef d'API ; si vous accédez à l'API depuis une application externe, + vous devez passer par cette méthode. + +Comme la méthode par cookie de session ne devrait pas être utilisée +en dehors du cadre interne au site et qu'elle marche par défaut +dans le cadre de ce dernier, nous ne décrirons pas outre mesure la manière +de l'utiliser. + +## Obtenir une clef d'API + +Il n'y a, à l'heure actuelle, pas d'interface accessible sur le site +pour obtenir une clef d'API. +Si vous désirez en obtenir une, demandez directement au respo info. + +!!!danger + + Votre clef d'API doit rester secrète. + Ne la transmettez à personne, ne l'inscrivez pas en dur dans votre code. + + Si votre clef a fuité, ou que vous soupçonnez qu'elle ait pu fuiter, + informez-en immédiatement l'équipe informatique ! + +## L'interface Swagger + +Avant de commencer à utiliser l'API du site, vous pouvez explorer +les différentes routes qu'elle met à disposition, +avec les schémas de données attendus en requête et en réponse. + +Pour cela, vous pouvez vous rendre sur +[https://ae.utbm.fr/api/docs](https://ae.utbm.fr/api/docs). + +Toutes les routes, à de rares exceptions près, y sont recensées. +Vous pouvez les utiliser dans les limites +de ce à quoi vos permissions vous donnent droit +et de la méthode d'authentification. + +Vous pouvez vous connecter directement sur l'interface Swagger, +en cliquant sur ce bouton, en haut à droite : + +![Swagger auth (1)](../img/api_key_authorize_1.png) +/// caption +Bouton d'autorisation sur Swagger +/// + +Puis rentrez votre clef d'API dans le champ prévu à cet effet, +et cliquez sur authorize : + + +![Swagger auth (2)](../img/api_key_authorize_2.png) +/// caption +Saisie de la clef d'API +/// + +Les routes accessibles avec une clef d'API seront alors marquées par +une icône de cadenas fermé, sur la droite. + +!!!warning "Authentification et permissions" + + L'icône de cadenas signifie que la route accepte l'authentification + basée sur les clefs d'API, mais pas forcément que vous avez les + permissions nécessaires. + + Si une route vous renvoie une erreur 403, + référez-en à l'équipe info, pour qu'elle puisse vous donner + les permissions nécessaires. + +## Utiliser la clef d'API + +### `X-APIKey` + +Maintenant que vous avez la clef d'API, +il faut l'utiliser pour authentifier votre application +lorsqu'elle effectue des requêtes au site. + +Pour cela, vous devez le fournir dans vos requêtes +à travers le header `X-APIKey`. + +Par exemple : + +```shell +curl "https://ae.utbm.fr/api/club/1" \ + -H "X-APIKey: " +``` + +Comme votre clef d'API doit rester absolument secrète, +vous ne devez en aucun cas la mettre dans votre code. +À la place, vous pouvez créer un fichier (par exemple, un `.env`) +qui contiendra votre clef et qui sera gitignoré. + +```dotenv title=".env" +API_KEY="" +``` + +Vous fournirez alors la clef d'API en la chargeant depuis votre environnement. +Notez que c'est une bonne pratique à double-titre, +puisque vous pouvez ainsi aisément changer votre clef d'API. + +### Connexion persistante + +La plupart des librairies permettant d'effectuer des requêtes +HTTP incluent une prise en charge des sessions persistantes. +Nous vous recommandons fortement d'utiliser ces fonctionnalités, +puisqu'elles permettent de rendre votre code plus simple +(vous n'aurez à renseigner votre clef d'API qu'une seule fois) +et plus efficace (réutiliser la même connexion plutôt que d'en créer +une nouvelle à chaque requête peut résulter en un gain de performance significatif ; +cf. [HTTP persistant connection (wikipedia)](https://en.wikipedia.org/wiki/HTTP_persistent_connection)) + +Voici quelques exemples : + +=== "Python (requests)" + + Dépendances : + + - `requests` (>=2.32) + - `environs` (>=14.1) + + ```python + import requests + from environs import Env + + env = Env() + env.read_env() + + with requests.Session() as session: + session.headers["X-APIKey"] = env.str("API_KEY") + response = session.get("https://ae.utbm.fr/api/club/1") + print(response.json()) + ``` + +=== "Python (aiohttp)" + + Dépendances : + + - `aiohttp` (>=3.11) + - `environs` (>=14.1) + + ```python + import aiohttp + import asyncio + from environs import Env + + env = Env() + env.read_env() + + async def main(): + async with aiohttp.ClientSession( + base_url="https://ae.utbm.fr/api/", + headers={"X-APIKey": env.str("API_KEY")} + ) as session: + async with session.get("club/1") as res: + print(await res.json()) + + asyncio.run(main()) + ``` + +=== "Javascript (axios)" + + Dépendances : + + - `axios` (>=1.9) + - `dotenv` (>=16.5) + + ```javascript + import { axios } from "axios"; + import { config } from "dotenv"; + + config(); + + const instance = axios.create({ + baseUrl: "https://ae.utbm.fr/api/", + headers: { "X-APIKey": process.env.API_KEY } + }); + console.log(await instance.get("club/1").json()); + ``` + +=== "Rust (reqwest)" + + Dépendances : + + - `reqwest` (>= 0.12, features `json` et `gzip`) + - `tokio` (>= 1.44, feature `derive`) + - `dotenvy` (>= 0.15) + + ```rust + use reqwest::Client; + use reqwest::header::{HeaderMap, HeaderValue}; + use dotenvy::EnvLoader; + + + #[tokio::main] + async fn main() -> Result<(), Box> { + let env = EnvLoader::new().load()?; + let mut headers = HeaderMap::new(); + let mut api_key = HeaderValue::from_str(env.var("API_KEY")?.as_str()); + api_key.set_sensitive(true); + headers.insert("X-APIKey", api_key); + let client = Client::builder() + .default_headers(headers) + .gzip(true) + .build()?; + let resp = client + .get("https://ae.utbm.fr/api/club/1") + .send() + .await? + .json() + .await?; + println!("{resp:#?}"); + Ok(()) + } + ``` diff --git a/mkdocs.yml b/mkdocs.yml index 7201fd9d..7ad3da91 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -45,7 +45,6 @@ plugins: members: true members_order: source show_source: true - show_inherited_members: true merge_init_into_class: true show_root_toc_entry: false - include-markdown: @@ -67,6 +66,7 @@ nav: - Gestion des permissions: tutorial/perms.md - Gestion des groupes: tutorial/groups.md - Les fragments: tutorial/fragments.md + - Connexion à l'API: tutorial/connect-api.md - Etransactions: tutorial/etransaction.md - How-to: - L'ORM de Django: howto/querysets.md @@ -157,6 +157,7 @@ markdown_extensions: - pymdownx.details - pymdownx.inlinehilite - pymdownx.keys + - pymdownx.blocks.caption - pymdownx.superfences: custom_fences: - name: mermaid