Pregunta

Me estoy iniciando en la construcción de una API REST para un proyecto en el que estoy trabajando, y me llevó a investigar un poco sobre la mejor manera de crear una API con RoR. Descubrí rápidamente que, de manera predeterminada, los modelos están abiertos al mundo y pueden llamarse a través de la URL simplemente poniendo un " .xml " al final de la URL y pasando los parámetros apropiados.

Entonces vino la siguiente pregunta. ¿Cómo aseguro mi aplicación para evitar cambios no autorizados? Al hacer algunas investigaciones, encontré un par de artículos que hablan sobre attr_accessible y attr_protected y cómo se pueden usar. La URL particular que encontré hablando de estos se publicó en mayo de 2007 ( aquí ).

Como con todas las cosas ruby, estoy seguro de que las cosas han evolucionado desde entonces. Así que mi pregunta es, ¿sigue siendo esta la mejor manera de asegurar una API REST dentro de RoR?

Si no, ¿qué sugiere en un " nuevo proyecto " o un " escenario de proyecto existente "?

¿Fue útil?

Solución

Hay varios esquemas para autenticar solicitudes de API, y son diferentes a la autenticación normal proporcionada por complementos como restful_authentication o act_as_authenticated. Lo más importante es que los clientes no mantendrán sesiones, por lo que no hay un concepto de inicio de sesión.

Autenticación HTTP

Puedes usar autenticación HTTP básica. Para esto, los clientes de API usarán un nombre de usuario y una contraseña regulares y solo lo pondrán en la URL de esta manera:

http://myusername:mypass@www.someapp.com/

Creo que restful_authentication admite esto de forma inmediata, por lo que puede ignorar si alguien está usando su aplicación a través de la API o a través de un navegador.

Una desventaja aquí es que está pidiendo a los usuarios que pongan su nombre de usuario y contraseña en claro en cada solicitud. Al hacerlo a través de SSL, puede hacer esto seguro.

No creo que haya visto una API que use esto, sin embargo. Me parece una buena idea decente, especialmente porque los esquemas de autenticación actuales lo soportan de manera inmediata, por lo que no sé cuál es el problema.

Clave de API

Otra forma fácil de habilitar la autenticación de API es usar claves de API. Es esencialmente un nombre de usuario para un servicio remoto. Cuando alguien se registra para usar tu API, le das una clave de API. Esto debe pasarse con cada solicitud.

Una desventaja aquí es que si alguien obtiene la clave API de otra persona, puede hacer solicitudes como ese usuario. Creo que al hacer que todas sus solicitudes de API utilicen HTTPS (SSL), puede compensar este riesgo de alguna manera.

Otro inconveniente es que los usuarios usan las mismas credenciales de autenticación (la clave de la API) en todos los lugares donde van. Si quieren revocar el acceso a un cliente de API, su única opción es cambiar su clave de API, lo que deshabilitará a todos los demás clientes también. Esto se puede mitigar permitiendo a los usuarios generar múltiples claves API.

Clave de API + Firma de clave secreta

En desuso (más o menos): consulte OAuth a continuación

Significativamente más complejo es firmar la solicitud con una clave secreta. Esto es lo que hacen los servicios web de Amazon (S3, EC2 y otros). Esencialmente, le da al usuario 2 claves: su clave API (es decir, nombre de usuario) y su clave secreta (es decir, contraseña). La clave API se transmite con cada solicitud, pero la clave secreta no lo es. En su lugar, se utiliza para firmar cada solicitud, generalmente agregando otro parámetro.

IIRC, Amazon logra esto llevando todos los parámetros a la solicitud y ordenándolos por nombre de parámetro. Luego, esta cadena está en hash, utilizando la clave secreta del usuario como clave de hash. Este nuevo valor se agrega como un nuevo parámetro a la solicitud antes de ser enviado. Por el lado de Amazon, hacen lo mismo. Toman todos los parámetros (excepto la firma), los ordenan y el hash mediante la clave secreta. Si esto coincide con la firma, saben que la solicitud es legítima.

La desventaja aquí es la complejidad. Conseguir que este esquema funcione correctamente es un dolor, tanto para el desarrollador de API como para los clientes. Espere muchas llamadas de soporte y correos electrónicos enojados de desarrolladores clientes que no pueden hacer que las cosas funcionen.

OAuth

Para combatir algunos de los problemas de complejidad con la firma clave + secreta, ha surgido un estándar llamado OAuth . En el núcleo, OAuth es una combinación de clave + firma secreta, pero gran parte está estandarizada y se ha incluido en bibliotecas para muchos idiomas .

En general, es mucho más fácil que tanto el productor como el consumidor de API utilicen OAuth en lugar de crear su propio sistema de clave / firma.

OAuth también segmenta inherentemente el acceso, proporcionando diferentes credenciales de acceso para cada consumidor de API. Esto permite a los usuarios revocar selectivamente el acceso sin afectar sus otras aplicaciones consumidoras.

Específicamente para Ruby, hay una OAuth gema que brinda asistencia inmediata tanto para productores como para consumidores. de OAuth. He usado esta gema para crear una API y también para consumir las API de OAuth y quedé muy impresionado. Si crees que tu aplicación necesita OAuth (a diferencia del esquema de clave API más simple), puedo recomendar fácilmente el uso de la gema OAuth.

Otros consejos

  

¿Cómo aseguro mi aplicación para prevenir?   cambios no autorizados?

attr_accessible y attr_protected son útiles para controlar la capacidad de realizar asignaciones en masa en un modelo ActiveRecord. Definitivamente desea utilizar attr_protected para evitar ataques de inyección de formularios; vea Utilice attr_protected o lo hackearemos .

Además, para evitar que alguien pueda acceder a los controladores en su aplicación Rails, es casi seguro que necesitará algún tipo de sistema de autenticación de usuario y coloque un before_filter en sus controladores para asegurarse de que tiene un usuario autorizado que realiza la solicitud antes de permitir que se ejecute la acción del controlador solicitada.

Consulte la Guía de seguridad de Ruby on Rails (parte del Proyecto de documentación de Rails) para obtener más información información más útil.

Me enfrento a preguntas similares a las de usted en este momento porque también estoy creando una API REST para una aplicación de rieles.

Sugiero asegurarme de que solo los atributos que pueden ser editados por el usuario estén marcados con attr_accessible. Esto configurará una lista blanca de atributos que se pueden asignar utilizando update_attributes.

Lo que hago es algo como esto:

   class Model < ActiveRecord::Base  
       attr_accessible nil  
   end

Todos mis modelos heredan de eso, por lo que se ven obligados a definir attr_accessible para cualquier campo que quieran hacer asignable en masa. Personalmente, me gustaría que hubiera una manera de habilitar este comportamiento de forma predeterminada (podría haberlo, y no lo sé).

Solo para que sepa que alguien puede asignar una propiedad en masa no solo usando la API REST sino también mediante un formulario de publicación regular.

Otro enfoque que ahorra en la construcción de muchas cosas es usar algo como http://www.3scale.net / que maneja claves, tokens, cuotas, etc. para desarrolladores individuales. También hace análisis y crea un portal para desarrolladores.

Hay un complemento de ruby ??/ rails complemento API de ruby ?? que se aplicará a las políticas para el tráfico a medida que llegue. puede usarlo junto con la oAuth gema . También puede usarlo colocando barniz delante de la aplicación y utilizando el mod de lib barn: Módulo API de Barniz .

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top