0Pricing
R Academy · Aula

Autenticação e segurança de APIs

Adicione validação de chaves de API, cabeçalhos CORS e filtros de limitação de taxa.

Autenticação e segurança de APIs é uma aula grátis de R Academy no CoddyKit. Esta é a aula 3 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de R Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de R Academy inclui 4 aulas no total.

Por que a segurança da API é importante

Uma API do Plumber é um servidor HTTP público. Sem autenticação, qualquer pessoa que consiga alcançar a porta poderá chamar seus endpoints. As camadas de segurança incluem autenticação (quem é você?), autorização (o que você pode fazer?), validação de entrada e segurança do transporte.

Filtros do Plumber como middleware

Os filtros do Plumber são executados antes do manipulador da rota. Use pr_filter(name, function(req, res){...}) para adicionar um middleware que inspecione cada solicitação. Chame plumber::forward() para passar ao próximo filtro ou à rota; retorne imediatamente para rejeitar.

# 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)

Filtro de autenticação com chave de API

O padrão simples de autenticação mais comum para APIs servidor a servidor usa uma chave de API estática enviada em um cabeçalho. O filtro verifica o cabeçalho em cada solicitação e retorna 401 se ele estiver ausente ou incorreto.

# 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()
# }

Verificando o cabeçalho de autorização

Os tokens Bearer são enviados no cabeçalho Authorization: Bearer <token>. Acesse-o por meio de req$HTTP_AUTHORIZATION. Analise-o com strsplit() para extrair a parte do token e, em seguida, valide-a comparando-a com seu armazenamento.

# #* @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()
# }

Ignorando a autenticação com #* @preempt

Alguns endpoints (verificações de integridade e documentação pública) devem ignorar a autenticação. Anote-os com #* @preempt auth, em que auth corresponde ao nome do filtro. O Plumber encaminha a solicitação diretamente ao manipulador, ignorando esse filtro.

# #* 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 com pr_cors()

Se sua API for chamada por um navegador em um domínio diferente, será necessário habilitar CORS (compartilhamento de recursos entre origens). Use pr_cors() para configurar origens, métodos e cabeçalhos permitidos sem escrever cabeçalhos brutos manualmente.

# 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)

Higienização de entradas — nunca confie nas entradas do usuário

Sempre valide e higienize as entradas antes de usá-las em consultas ou operações de arquivo:

  • Verifique o tipo: is.numeric(), is.character()
  • Verifique o intervalo: id >= 1 && id <= 1e9
  • Rejeite caracteres inesperados: grepl('[^a-zA-Z0-9_]', name)
  • Nunca interpole diretamente strings do usuário em SQL — use consultas parametrizadas
# #* @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))
# }

Conceitos de limitação de taxa

O Plumber não tem um limitador de taxa integrado, mas você pode implementar um em um filtro usando um ambiente compartilhado para acompanhar as contagens de solicitações por IP:

  • Registre o horário de cada solicitação por IP em um ambiente do R
  • Rejeite com 429 se a contagem exceder o limite dentro da janela
  • Em produção, use um proxy reverso como o nginx para limitar a taxa
# 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()
# }

Armazenando chaves de API com segurança

Nunca inclua segredos diretamente nos arquivos de código-fonte. Armazene-os em variáveis de ambiente e leia-os na inicialização com Sys.getenv(). Use um arquivo .env localmente (excluído do git) e injete os segredos por meio do ambiente de implantação em produção.

# 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
')

Anexando o contexto do usuário à solicitação

Depois de validar um token no filtro de autenticação, anexe as informações decodificadas do usuário ao objeto req para que os manipuladores posteriores possam acessá-las sem validá-las novamente. Os campos personalizados de req persistem em toda a cadeia de filtros.

# #* @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)
# }

Tratamento de erros com tryCatch

Envolva a lógica do endpoint em tryCatch() para capturar erros inesperados e retornar uma resposta 500 limpa, em vez de encerrar o processo de trabalho ou expor um rastreamento da pilha ao chamador.

# #* @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')
#   })
# }

Verificação rápida: anotação @preempt

O que a anotação #* @preempt auth faz com um endpoint do Plumber?

Recapitulação da segurança de APIs

Proteger uma API do Plumber envolve defesas em camadas:

  • pr_filter('auth', ...) — inspeciona cada solicitação no middleware
  • req$HTTP_AUTHORIZATION / req$HTTP_X_API_KEY — lê os cabeçalhos de autenticação
  • #* @preempt auth — ignora a autenticação em endpoints públicos
  • pr_cors() — configura o acesso entre origens do navegador
  • Validação das entradas antes de qualquer operação de banco de dados ou arquivo
  • Sys.getenv() para segredos — nunca inclua chaves diretamente no código

Perguntas Frequentes

A aula “Autenticação e segurança de APIs” é grátis?

Sim — o texto completo de “Autenticação e segurança de APIs” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de R Academy, atualize para CoddyKit PRO. O curso de R Academy inclui 4 aulas no total.

O que vou aprender em “Autenticação e segurança de APIs”?

Adicione validação de chaves de API, cabeçalhos CORS e filtros de limitação de taxa. Você pratica R Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar R Academy?

Nenhuma experiência prévia é necessária. R Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 3 de 4.

Quanto tempo leva a aula “Autenticação e segurança de APIs”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de R Academy?

Sim. Cada aula de R Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Introdução ao Plumber e REST
  2. Criando endpoints GET e POST
  3. Autenticação e segurança de APIs
  4. Implantando APIs Plumber em produção
← Voltar para R Academy