Autenticación y Seguridad en CRUD de Posts en Rails

Clase 24 de 33Curso de Creación de APIs con Ruby on Rails

Resumen

Proteger endpoints en Rails requiere unir autenticación, autorización y pruebas claras. Aquí verás cómo asociar posts al usuario autenticado, controlar la visibilidad en show y resolver errores comunes en specs con with_indifferent_access y byebug. El enfoque: seguridad primero, pruebas confiables y correcciones puntuales.

Implementación con current user

La base es el método authenticate user que valida el header de autorización y el token. Con esto activo, se refuerzan las acciones que modifican datos y se evita pasar el user_id desde parámetros.

¿Cómo asegurar create y update con current_user?

  • Usar la asociación: user has_many posts para crear en contexto del usuario.
  • Evitar recibir user_id en params para no exponer asignaciones indebidas.
  • En update, buscar el post dentro de los del usuario autenticado.
# create
def create
  post = current_user.posts.create(post_params)
  render json: post
end

# update
def update
  post = current_user.posts.find(params[:id])
  post.update(update_params)
  render json: post
end

¿Qué pasa con los parámetros en create params?

  • Quitar el permiso de :user_id.
  • Confiar en current user y su relación con posts para la autoría.
  • Mantener solo los atributos del post que sí se pueden modificar.

Visibilidad y autorización en show

La lectura no siempre requiere autenticación, pero sí control de visibilidad. Se permite ver si el post es público. Si no lo es, solo el usuario autenticado propietario puede acceder; de lo contrario, devolver 404 not found con un error "Not found".

¿Cuándo mostrar un post público o privado?

  • Si el post es público: permitir render directo.
  • Si no es público y hay current user dueño: permitir render.
  • En cualquier otro caso: responder con status not_found (404).
if post_public || (current_user && post.user == current_user)
  render json: post
else
  render json: { error: "Not found" }, status: :not_found
end

Pruebas y debugging en Rails

Ajustar specs evita falsos negativos. Aquí se corrigen desajustes de tipos (símbolos vs cadenas), se crea un helper para el payload y se depura un 500 ocasionado por un método mal escrito.

¿Cómo resolver el error de ID símbolo vs string?

  • El payload respondió con "id" como cadena, la prueba esperaba símbolo.
  • Ajustar aserciones para aceptar ambos formatos de clave.
  • Crear un helper reutilizable para analizar la respuesta.
# Helper en la prueba
private

def payload
  # hash_response es el cuerpo parseado de la respuesta
  hash_response.with_indifferent_access
end

¿Cómo usar with_indifferent_access en un helper payload?

  • Aplicarlo al hash del payload para acceder con símbolo o cadena.
  • Beneficio: aserciones más robustas y legibles.
  • Clave en Rails: with_indifferent_access sobre hashes de respuesta.
expect(payload[:id]).to be_present
expect(payload["id"]).to be_present

¿Cómo depurar un 500 y corregir attribute vs attributes?

  • Fallo: se esperaba 404 not found, se obtuvo 500.
  • Estrategia: insertar byebug en el controller y ejecutar la spec por línea.
  • Detectado: uso incorrecto de attributes en lugar de attribute en el flujo de current.
  • Corrección: cambiar al método correcto y re-ejecutar, las pruebas pasan.
# En el controller
require 'byebug'
byebug  # punto de parada para inspección

# En terminal (ejemplo de ejecución por línea)
rspec spec/path/private_post_spec.rb:36

¿Te quedó alguna duda sobre el flujo con current user o el manejo de errores 404/500? Comparte tus preguntas o el fragmento de código donde te atascaste, y lo revisamos juntos.