Se a protect_from_forgery
opção for mencionada em application_controller, eu posso efetuar login e executar quaisquer solicitações GET, mas na primeira solicitação POST, o Rails redefine a sessão, o que me desconecta.
protect_from_forgery
Desativei a opção temporariamente, mas gostaria de usá-la com o Angular.js. Existe alguma maneira de fazer isso?
Respostas:
Acho que ler o valor CSRF do DOM não é uma boa solução, é apenas uma solução alternativa.
Aqui está um formulário no site oficial do angularJS http://docs.angularjs.org/api/ng.$http :
Aqui está minha solução com base nessas instruções:
Primeiro, defina o cookie:
Em seguida, devemos verificar o token em todas as solicitações não GET.
Como o Rails já construiu com o método semelhante, podemos simplesmente substituí-lo para acrescentar nossa lógica:
fonte
Se você estiver usando a proteção padrão do Rails CSRF (
<%= csrf_meta_tags %>
), poderá configurar seu módulo Angular assim:Ou, se você não estiver usando o CoffeeScript (o que !?):
Se preferir, você pode enviar o cabeçalho apenas em solicitações não GET com algo como o seguinte:
Além disso, verifique a resposta do HungYuHei , que cobre todas as bases do servidor e não do cliente.
fonte
<%= csrf_meta_tags %>
. Eu pensei que deveria haver o suficiente para mencionarprotect_from_forgery
apenas. O que fazer? O documento base deve ser um HTML simples (aqui não sou eu quem escolhe).protect_from_forgery
o que está dizendo é "quando meu código JavaScript faz solicitações do Ajax, prometo enviar umX-CSRF-Token
no cabeçalho que corresponda ao token CSRF atual". Para obter esse token, o Rails o injeta no DOM<%= csrf_meta_token %>
e obtém o conteúdo da metatag com o jQuery sempre que ele solicita o Ajax (o driver UJS padrão do Rails 3 faz isso por você). Se você não estiver usando o ERB, não há como inserir o token atual do Rails na página e / ou no JavaScript - e, portanto, você não pode usáprotect_from_forgery
-lo dessa maneira.csrf_meta_tags
cada vez que o servidor gera uma resposta e cada vez que essas tags são diferentes das anteriores. Portanto, essas tags são exclusivas para cada solicitação. A questão é: como o aplicativo recebe essas tags para uma solicitação AJAX (sem angular)? Usei protect_from_forgery com solicitações jQuery POST, nunca me incomodei em obter esse token CSRF e funcionou. Quão?jQuery.ajaxPrefilter
como mostrado aqui: github.com/indirect/jquery-rails/blob/c1eb6ae/vendor/assets/… Você pode ler este arquivo e ver todos os aros que o Rails percorre para fazê-lo funcionar praticamente sem precisar preocupado com isso.put
epost
não em vez dissocommon
? A partir do guia de segurança trilhos :The solution to this is including a security token in non-GET requests
A gem angular_rails_csrf adiciona automaticamente suporte ao padrão descrito na resposta de HungYuHei a todos os seus controladores:
fonte
angular_rails_csrf
gem não funciona com o Rails 5. No entanto, a configuração de cabeçalhos de solicitação Angular com o valor da metatag CSRF funciona!A resposta que mescla todas as respostas anteriores e conta que você está usando a
Devise
jóia de autenticação.Primeiro de tudo, adicione a gema:
Em seguida, adicione
rescue_from
bloco no application_controller.rb:E, finalmente, adicione o módulo interceptador ao seu aplicativo angular.
fonte
$injector
vez de apenas injetando diretamente$http
?Vi as outras respostas e achei que eram ótimas e bem pensadas. Embora meu aplicativo Rails funcionasse com o que eu pensava ser uma solução mais simples, pensei em compartilhar. Meu aplicativo rails veio com esse padrão,
Eu li os comentários e parecia que é isso que eu quero usar angular e evitar o erro csrf. Eu mudei para isso,
E agora funciona! Não vejo nenhuma razão para que isso não funcione, mas eu adoraria ouvir algumas dicas de outros pôsteres.
fonte
Eu usei o conteúdo da resposta de HungYuHei no meu aplicativo. No entanto, descobri que estava lidando com alguns problemas adicionais, alguns por causa do uso do Devise para autenticação e outros por causa do padrão que obtive com meu aplicativo:
Observo a pergunta relacionada ao estouro de pilha e as respostas lá e escrevi uma postagem de blog muito mais detalhada que resume as várias considerações. As partes dessa solução que são relevantes aqui são, no controlador de aplicativo:
fonte
Eu encontrei um hack muito rápido para isso. Tudo o que eu precisava fazer era o seguinte:
uma. Na minha opinião, eu inicializo uma
$scope
variável que contém o token, digamos antes do formulário, ou ainda melhor na inicialização do controlador:b. No meu controlador AngularJS, antes de salvar minha nova entrada, adiciono o token ao hash:
Nada mais precisa ser feito.
fonte
Está trabalhando no lado do angularjs!
fonte