Quiero hacerle POST request
a mi desarrollador local, así:
HTTParty.post('http://localhost:3000/fetch_heroku',
:body => {:type => 'product'},)
Sin embargo, desde la consola del servidor informa
Started POST "/fetch_heroku" for 127.0.0.1 at 2016-02-03 23:33:39 +0800
ActiveRecord::SchemaMigration Load (0.0ms) SELECT "schema_migrations".* FROM "schema_migrations"
Processing by AdminController#fetch_heroku as */*
Parameters: {"type"=>"product"}
Can't verify CSRF token authenticity
Completed 422 Unprocessable Entity in 1ms
Aquí está mi controlador y configuración de rutas, es bastante simple.
def fetch_heroku
if params[:type] == 'product'
flash[:alert] = 'Fetch Product From Heroku'
Heroku.get_product
end
end
post 'fetch_heroku' => 'admin#fetch_heroku'
¿No estoy seguro de lo que debo hacer? Desactivar el CSRF ciertamente funcionaría, pero creo que debería ser mi error al crear una API de este tipo.
¿Hay alguna otra configuración que deba hacer?
ruby-on-rails
cqcn1991
fuente
fuente
protect_from_forgery with: :null_session
.Respuestas:
La falsificación de solicitudes entre sitios (CSRF / XSRF) se produce cuando una página web maliciosa engaña a los usuarios para que realicen una solicitud que no está destinada, por ejemplo, mediante el uso de marcadores, iframes o simplemente creando una página que sea visualmente lo suficientemente similar como para engañar a los usuarios.
La protección CSRF de Rails está hecha para aplicaciones web "clásicas"; simplemente brinda un grado de seguridad de que la solicitud se originó en su propia aplicación web. Un token CSRF funciona como un secreto que solo su servidor conoce: Rails genera un token aleatorio y lo almacena en la sesión. Sus formularios envían el token a través de una entrada oculta y Rails verifica que cualquier solicitud que no sea GET incluya un token que coincida con lo que está almacenado en la sesión.
Sin embargo, una API suele ser, por definición, entre sitios y está destinada a ser utilizada en más que su aplicación web, lo que significa que todo el concepto de CSRF no se aplica del todo.
En su lugar, debe utilizar una estrategia basada en token para autenticar las solicitudes de API con una clave y un secreto de API, ya que está verificando que la solicitud proviene de un cliente de API aprobado, no de su propia aplicación.
Puede desactivar CSRF como lo señala @dcestari:
class ApiController < ActionController::Base protect_from_forgery with: :null_session end
Actualizado. En Rails 5 puede generar aplicaciones solo API usando la
--api
opción:rails new appname --api
No incluyen el middleware CSRF y muchos otros componentes superfluos.
fuente
Otra forma de desactivar CSRF que no generará una sesión nula es agregar:
skip_before_action :verify_authenticity_token
en su controlador Rails. Esto asegurará que aún tenga acceso a la información de la sesión.
Nuevamente, asegúrese de hacer esto solo en controladores API o en otros lugares donde la protección CSRF no se aplica del todo.
fuente
protect_from_forgery except: [:my_method_name]
?Hay información relevante sobre una configuración de CSRF con respecto a los controladores API en api.rubyonrails.org :
fuente
protect_from_forgery
todavía es necesario para las API y las fuentes que dicen que no lo es. ¿Qué pasa si la API es para una aplicación de una sola página, que usa la cookie de sesión para la autenticación del usuario?Desde Rails 5 también puede crear una nueva clase con :: API en lugar de :: Base:
class ApiController < ActionController::API end
fuente
Si desea excluir la acción de muestra del controlador de muestra
class TestController < ApplicationController protect_from_forgery :except => [:sample] def sample render json: @hogehoge end end
Puede procesar solicitudes desde el exterior sin ningún problema.
fuente
La solución más simple para el problema es hacer cosas estándar en su controlador o puede ponerlo directamente en ApplicationController
class ApplicationController < ActionController::Base protect_from_forgery with: :exception, prepend: true end
fuente