Eu quero fazer POST request
para meu desenvolvedor local, assim:
HTTParty.post('http://localhost:3000/fetch_heroku',
:body => {:type => 'product'},)
No entanto, a partir do console do servidor, ele relata
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
Aqui está meu controlador e configuração de rotas, é bastante simples.
def fetch_heroku
if params[:type] == 'product'
flash[:alert] = 'Fetch Product From Heroku'
Heroku.get_product
end
end
post 'fetch_heroku' => 'admin#fetch_heroku'
Não tenho certeza do que preciso fazer? Desligar o CSRF certamente funcionaria, mas acho que deveria ser meu erro ao criar tal API.
Há alguma outra configuração que preciso fazer?
ruby-on-rails
cqcn1991
fonte
fonte
protect_from_forgery with: :null_session
.Respostas:
Falsificação de solicitação entre sites (CSRF / XSRF) ocorre quando uma página da web mal-intencionada engana os usuários para que executem uma solicitação que não se destina, por exemplo, ao uso de bookmarklets, iframes ou apenas criando uma página visualmente semelhante o suficiente para enganar os usuários.
A proteção Rails CSRF é feita para aplicativos da web "clássicos" - ela simplesmente oferece um grau de garantia de que a solicitação originou-se de seu próprio aplicativo da web. Um token CSRF funciona como um segredo que apenas o seu servidor conhece - o Rails gera um token aleatório e o armazena na sessão. Seus formulários enviam o token através de uma entrada oculta e o Rails verifica se qualquer solicitação não GET inclui um token que corresponde ao que está armazenado na sessão.
No entanto, uma API é geralmente, por definição, entre sites e deve ser usada em mais do que seu aplicativo da web, o que significa que todo o conceito de CSRF não se aplica.
Em vez disso, você deve usar uma estratégia baseada em token de autenticação de solicitações de API com uma chave e segredo de API, já que está verificando se a solicitação vem de um cliente de API aprovado - não de seu próprio aplicativo.
Você pode desativar o CSRF conforme apontado por @dcestari:
class ApiController < ActionController::Base protect_from_forgery with: :null_session end
Atualizada. No Rails 5 você pode gerar aplicativos somente API usando a
--api
opção:rails new appname --api
Eles não incluem o middleware CSRF e muitos outros componentes que são superflouus.
fonte
Outra maneira de desligar o CSRF que não renderizará uma sessão nula é adicionar:
skip_before_action :verify_authenticity_token
em seu controlador Rails. Isso garantirá que você ainda tenha acesso às informações da sessão.
Novamente, certifique-se de fazer isso apenas em controladores de API ou em outros lugares onde a proteção CSRF não se aplica.
fonte
protect_from_forgery except: [:my_method_name]
?Há informações relevantes sobre a configuração do CSRF em relação aos controladores de API em api.rubyonrails.org :
fonte
protect_from_forgery
ainda é necessário para APIs e fontes que dizem que não é. E se a API for para um aplicativo de página única, que usa o cookie de sessão para autenticação do usuário?Desde o Rails 5 você também pode criar uma nova classe com :: API em vez de :: Base:
class ApiController < ActionController::API end
fonte
Se você deseja excluir a ação de amostra do controlador de amostra
class TestController < ApplicationController protect_from_forgery :except => [:sample] def sample render json: @hogehoge end end
Você pode processar solicitações de fora sem problemas.
fonte
A solução mais simples para o problema é fazer coisas padrão em seu controlador ou você pode colocá-lo diretamente em ApplicationController
class ApplicationController < ActionController::Base protect_from_forgery with: :exception, prepend: true end
fonte
Se você deseja apenas pular a proteção CSRF para uma ou mais ações do controlador (em vez de todo o controlador), tente isto
skip_before_action :verify_authenticity_token, only [:webhook, :index, :create]
Onde
[:webhook, :index, :create]
pulará a verificação dessas 3 ações, mas você pode mudar para a que deseja pularfonte