2009-12-03 12 views
5

Estoy utilizando REST y OAuth para hablar con una aplicación de Rails (desde una aplicación de iPhone, pero eso no debería ser relevante). Sin embargo, estoy teniendo algunos problemas con la protección CSRF de Rails (a través de protects_from_forgery).Rails, OAuth y protección CSRF

Entiendo que la protección CSRF solo se activa para envíos de formularios regulares (es decir, Content-Type = application/x-www-form-urlencoded), así que estaría bien si estuviera enviando datos JSON o XML. Desafortunadamente, OAuth actualmente se limita a las solicitudes application/x-www-form-urlencoded. Hay un draft spec that extends OAuth to non-form-urlencoded data, pero esto no me ayuda en este momento.

La forma en que lo veo, tengo las siguientes opciones:

  1. enviar los datos como JSON, sabiendo que no sería parte de la firma de OAuth y por lo tanto sujeta al hombre-en-el ataques medios. Obviamente no es una solución atractiva.

  2. Cree acciones especiales de rieles (por ejemplo, UsersController#update_oauth) que deleguen internamente en las acciones normales (por ejemplo, UsersController#update). Luego, excluya estos de la protección contra falsificaciones (protects_from_forgery :only => [:update]). Esto debería funcionar y podría ser aceptable en el límite para una o dos acciones, pero obviamente sería una solución muy complicada.

  3. Anula la protección CSRF de los rieles para ignorar las solicitudes de OAuth. No he intentado esto, pero parece que debería ser posible cambiar uno de los ganchos (quizás el filtro verify_authenticity_token) para considerar que las solicitudes de OAuth son exitosas.

¿Alguien ha topado con esto antes? ¿Alguna recomendación? ¿O quizás me estoy perdiendo algo básico?

Respuesta

5

Voy a responder mi propia pregunta. :)

Agregué el siguiente método a nuestras extensiones de controlador OAuth. Lo único que se agrega a la implementación predeterminada es el cheque oauth?. Esto parece ser el truco y se siente como una solución bastante limpia.

def verify_authenticity_token 
    verified_request? || oauth? || raise(ActionController::InvalidAuthenticityToken)  
end 
Cuestiones relacionadas