0Pricing
R Academy · Leçon

Authentification et sécurité des API

Ajoutez la validation des clés d’API, les en-têtes CORS et des filtres de limitation du débit.

Authentification et sécurité des API est une leçon R Academy gratuite sur CoddyKit. Ceci est la leçon 3 sur 4. Tu peux lire la leçon complète ci-dessous gratuitement — puis la pratiquer en direct dans le navigateur avec un éditeur de code intégré et un tuteur IA 24/7. Elle fait partie du parcours d'apprentissage R Academy, et ta progression se synchronise sur le web et l'application CoddyKit. Le cours R Academy comprend 4 leçons au total.

Pourquoi la sécurité des API est importante

Une API Plumber est un serveur HTTP public. Sans authentification, toute personne pouvant accéder au port peut appeler vos points de terminaison. Les couches de sécurité comprennent l’authentification (qui êtes-vous ?), l’autorisation (que pouvez-vous faire ?), la validation des entrées et la sécurité du transport.

Les filtres Plumber comme intergiciel

Les filtres de Plumber s’exécutent avant le gestionnaire de route. Utilisez pr_filter(name, function(req, res){...}) pour ajouter un intergiciel qui inspecte chaque requête. Appelez plumber::forward() pour passer au filtre ou à la route suivante ; effectuez un retour anticipé pour rejeter la requête.

# library(plumber)
# pr <- plumb('api.R')
# pr |>
#   pr_filter('logger', function(req, res) {
#     cat(req$REQUEST_METHOD, req$PATH_INFO, '
')
#     plumber::forward()  # must call to continue
#   }) |>
#   pr_run(port = 8000)

Filtre d’authentification par clé d’API

Pour les API serveur-à-serveur, le modèle d’authentification simple le plus courant consiste à transmettre une clé d’API statique dans un en-tête. Le filtre vérifie l’en-tête pour chaque requête et renvoie 401 s’il est absent ou incorrect.

# In api.R:
# VALID_KEY <- Sys.getenv('API_SECRET_KEY')
#
# #* @filter auth
# function(req, res) {
#   key <- req$HTTP_X_API_KEY
#   if (is.null(key) || key != VALID_KEY) {
#     res$status <- 401L
#     return(list(error = 'Unauthorized'))
#   }
#   plumber::forward()
# }

Vérifier l’en-tête d’autorisation

Les jetons Bearer sont transmis dans l’en-tête Authorization: Bearer <token>. Accédez-y via req$HTTP_AUTHORIZATION. Analysez-le avec strsplit() pour extraire la partie contenant le jeton, puis validez celle-ci par rapport à votre référentiel.

# #* @filter bearer_auth
# function(req, res) {
#   auth_header <- req$HTTP_AUTHORIZATION
#   if (is.null(auth_header) || !startsWith(auth_header, 'Bearer ')) {
#     res$status <- 401L
#     return(list(error = 'Bearer token required'))
#   }
#   token <- substring(auth_header, 8)  # strip 'Bearer '
#   if (!token_is_valid(token)) {
#     res$status <- 401L
#     return(list(error = 'Invalid token'))
#   }
#   plumber::forward()
# }

Ignorer l’authentification avec #* @preempt

Certains points de terminaison (vérifications d’état, documentation publique) doivent ignorer l’authentification. Annotez-les avec #* @preempt auth, où auth correspond au nom du filtre. Plumber achemine directement la requête vers le gestionnaire, en contournant ce filtre.

# #* Health check — no auth required
# #* @preempt auth
# #* @get /ping
# function() {
#   list(status = 'ok', time = as.character(Sys.time()))
# }
#
# #* Protected endpoint — goes through auth filter
# #* @get /data
# function() {
#   list(secret = 'sensitive data')
# }

CORS avec pr_cors()

Si votre API est appelée depuis un navigateur situé sur un autre domaine, vous devez activer CORS (partage des ressources entre origines). Utilisez pr_cors() pour configurer les origines, méthodes et en-têtes autorisés sans écrire manuellement les en-têtes bruts.

# library(plumber)
# pr <- plumb('api.R')
# pr |>
#   pr_cors(
#     origin            = 'https://myapp.example.com',
#     methods           = c('GET', 'POST'),
#     headers           = c('Content-Type', 'X-API-Key'),
#     credentials       = TRUE
#   ) |>
#   pr_run(port = 8000)

Nettoyage des entrées — ne faites jamais confiance aux entrées utilisateur

Validez et nettoyez toujours les entrées avant de les utiliser dans des requêtes ou des opérations sur des fichiers :

  • Vérifiez le type : is.numeric(), is.character()
  • Vérifiez l’intervalle : id >= 1 && id <= 1e9
  • Rejetez les caractères inattendus : grepl('[^a-zA-Z0-9_]', name)
  • N’intégrez jamais directement les chaînes fournies par l’utilisateur dans SQL : utilisez des requêtes paramétrées
# #* @post /search
# function(req, res) {
#   body <- jsonlite::fromJSON(req$postBody)
#   query <- body$query
#   if (!is.character(query) || nchar(query) > 200) {
#     res$status <- 400L
#     return(list(error = 'query must be a string <= 200 chars'))
#   }
#   if (grepl('[;\'"]', query)) {
#     res$status <- 400L
#     return(list(error = 'Invalid characters in query'))
#   }
#   list(results = search_db(query))
# }

Notions de limitation du débit

Plumber ne dispose d’aucun limiteur de débit intégré, mais vous pouvez en implémenter un dans un filtre à l’aide d’un environnement partagé pour suivre le nombre de requêtes par IP :

  • Enregistrez l’horodatage de chaque requête par IP dans un environnement R
  • Rejetez la requête avec 429 si le nombre dépasse la limite pendant la fenêtre
  • En production, utilisez un proxy inverse comme nginx pour limiter le débit
# request_log <- new.env()
#
# #* @filter rate_limit
# function(req, res) {
#   ip <- req$REMOTE_ADDR
#   now <- as.numeric(Sys.time())
#   if (!exists(ip, envir = request_log)) assign(ip, c(), envir = request_log)
#   times <- get(ip, envir = request_log)
#   times <- times[times > now - 60]   # last 60 seconds
#   if (length(times) >= 60) { res$status <- 429L; return(list(error='Too Many Requests')) }
#   assign(ip, c(times, now), envir = request_log)
#   plumber::forward()
# }

Stocker les clés d’API en toute sécurité

Ne codez jamais les secrets en dur dans les fichiers source. Stockez-les dans des variables d’environnement et lisez-les au démarrage avec Sys.getenv(). Utilisez un fichier .env en local (exclu de git) et injectez les secrets via l’environnement de déploiement en production.

# In .env (never commit this file):
# API_SECRET_KEY=my_super_secret_key_here
#
# In api.R:
# VALID_KEY <- Sys.getenv('API_SECRET_KEY', unset = '')
# if (nchar(VALID_KEY) == 0) stop('API_SECRET_KEY not set')
#
# Load .env locally (devtools::load_dot_env or Sys.setenv):
# readRenviron('.env')
cat('Sys.getenv reads API keys without exposing them in source
')

Associer le contexte utilisateur à la requête

Après avoir validé un jeton dans le filtre d’authentification, associez les informations utilisateur décodées à l’objet req afin que les gestionnaires en aval puissent y accéder sans effectuer une nouvelle validation. Les champs personnalisés de req sont conservés tout au long de la chaîne de filtres.

# #* @filter auth
# function(req, res) {
#   token <- req$HTTP_AUTHORIZATION
#   user <- validate_token(token)  # returns list(id=1, role='admin')
#   if (is.null(user)) { res$status <- 401L; return(list(error='Unauthorized')) }
#   req$user <- user   # attach to request
#   plumber::forward()
# }
#
# #* @get /profile
# function(req) {
#   list(user_id = req$user$id, role = req$user$role)
# }

Gérer les erreurs avec tryCatch

Encapsulez la logique de votre point de terminaison dans tryCatch() afin d’intercepter les erreurs inattendues et de renvoyer une réponse 500 propre au lieu de faire planter le processus de travail ou d’exposer une trace d’appels à l’appelant.

# #* @get /risky/<id:int>
# function(id, res) {
#   tryCatch({
#     result <- risky_db_call(id)
#     list(data = result)
#   }, error = function(e) {
#     message('Error in /risky: ', conditionMessage(e))
#     res$status <- 500L
#     list(error = 'Internal server error')
#   })
# }

Vérification rapide : annotation @preempt

Que fait l’annotation #* @preempt auth sur un point de terminaison Plumber ?

Récapitulatif de la sécurité des API

Sécuriser une API Plumber nécessite plusieurs couches de défense :

  • pr_filter('auth', ...) — inspecter chaque requête dans l’intergiciel
  • req$HTTP_AUTHORIZATION / req$HTTP_X_API_KEY — lire les en-têtes d’authentification
  • #* @preempt auth — ignorer l’authentification pour les points de terminaison publics
  • pr_cors() — configurer l’accès interorigines depuis les navigateurs
  • Valider les entrées avant toute opération sur une base de données ou un fichier
  • Sys.getenv() pour les secrets — ne codez jamais les clés en dur

Questions Fréquemment Posées

La leçon « Authentification et sécurité des API » est-elle gratuite ?

Oui — le texte complet de « Authentification et sécurité des API » est gratuit à lire ici sur le web. Pour la pratiquer de manière interactive (un éditeur de code intégré et un tuteur IA 24/7) et déverrouiller le reste du cours R Academy, passe à CoddyKit PRO. Le cours R Academy comprend 4 leçons au total.

Qu'est-ce que j'apprendrai dans « Authentification et sécurité des API » ?

Ajoutez la validation des clés d’API, les en-têtes CORS et des filtres de limitation du débit. Tu pratiques R Academy avec du code pratique que tu exécutes directement dans le navigateur, et un tuteur IA 24/7 répond à tes questions au fur et à mesure que tu avances dans la leçon.

Dois-je avoir de l'expérience pour commencer R Academy ?

Aucune expérience préalable n'est requise. R Academy sur CoddyKit est structuré pour les débutants jusqu'aux apprenants avancés, donc tu peux commencer ici ou depuis le début et avancer à ton rythme. Ceci est la leçon 3 sur 4.

Combien de temps prend la leçon « Authentification et sécurité des API » ?

La plupart des leçons CoddyKit prennent environ 5–10 minutes. Chacune est courte et interactive, tu progresses régulièrement et tu repiques exactement où tu t'es arrêté sur le web et l'app.

Peux-tu écrire et exécuter du code dans cette leçon R Academy ?

Oui. Chaque leçon R Academy inclut un éditeur de code intégré, tu écris et exécutes du vrai code directement dans ton navigateur et tu reçois des retours IA instantanés — aucune configuration locale requise.

Toutes les leçons de ce cours

  1. Introduction à Plumber et REST
  2. Créer des points d’accès GET et POST
  3. Authentification et sécurité des API
  4. Déployer des API Plumber en production
← Retour à R Academy