ActionController :: InvalidAuthenticityToken


148

Aşağıda, Rails uygulamamdaki bir formun neden olduğu bir hata var:

Processing UsersController#update (for **ip** at 2010-07-29 10:52:27) [PUT]
  Parameters: {"commit"=>"Update", "action"=>"update", "_method"=>"put", "authenticity_token"=>"ysiDvO5s7qhJQrnlSR2+f8jF1gxdB7T9I2ydxpRlSSk=", **more parameters**}

ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):

Bu her isteksizlik için olur getve gördüğünüz gibi authenticity_tokenoradadır.

Yanıtlar:


207

Aynı sorunu yaşadım ama sayfa önbelleğe alınmış sayfalarda. Sayfalar eski bir kimlik doğrulama jetonu ve sahtekarlık girişimi olarak tanındığında post / put / delete yöntemlerini kullanarak tüm eylemlerle arabelleğe alındı. Hata (422 İşlenemeyen Varlık) kullanıcıya geri döndü.

Rails 3 için çözüm:
Ekle:

 skip_before_filter :verify_authenticity_token  

veya Rails 4'te belirtildiği gibi "sagivo" olarak ekleyin:

 skip_before_action :verify_authenticity_token

Önbellekleme yapan sayfalarda.

@Toobulkeh yorumladı gibi bu konuda bir güvenlik açığı değil :index, :showeylemler, ancak bu kullanarak dikkat :put, :posteylemler.

Örneğin:

 caches_page :index, :show  
 skip_before_filter :verify_authenticity_token, :only => [:index, :show]

Referans: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection/ClassMethods.html

Barlop- Rails 4.2 tarafından eklenen not, skip_before_action lehine skip_before_filter kullanımdan kaldırıldı https://guides.rubyonrails.org/4_2_release_notes.html "* _filter yöntem ailesi dokümantasyondan kaldırıldı. * _Action lehine kullanımı önerilmez yöntem ailesi "

İçin Raylar 6 kullanabilirsiniz ( "collimarco" belirttiği gibi) skip_forgery_protectionve oturum verileri kullanmayan bir REST API için kullanmak güvenli olduğunu.


3
Durum böyle değil, yazıdan önce caches_page bilmiyordum . Ama caches_page'i kontrol edeceğim , teşekkürler.
Nikita Rybak

7
raylarda 4skip_before_action :verify_authenticity_token
Sagiv Ofek

88
Bu bir güvenlik açığı değil mi?
quantumpotato

6
bu :index, :showeylemlerdeki bir güvenlik açığı değildir . Ama bunu :put, :posteyleme geçirmeye karşı dikkatli olun !
toobulkeh

14
Her ne kadar bazen bunun gerekli olduğu konusunda bir fikriniz olduğunu kabul ediyorum (belki de bir kez yaşamda olduğu gibi), ancak güvenliği devre dışı bırakarak güvenliği düzelttiğinizi fark etmeniz gerekir. Tavsiye
equivalent8

77

Benim için Rails 4 altındaki bu sorunun nedeni eksikti,

<%= csrf_meta_tags %>

Ana uygulama düzenimdeki satır. Düzenimi yeniden yazdığımda yanlışlıkla sildim.

Bu ana düzende değilse, bir CSRF jetonu olmasını istediğiniz herhangi bir sayfada buna ihtiyacınız olacaktır.


2
Bu hatayı da alıyoruz. Ama ara verildi. Nedeni bu olabilir mi yoksa buna sahip olmamak her talebi bir hata ile etkiler mi?
Ryan-Neal Mes

@ Ryan-NealMes, şablonunuzda bu satır eksikse hatayı alırsınız. Bu nedenle, bazı şablonlarınızda bazılarının olması ve diğerlerinde bulunmaması mümkündür.
James McMahon

1
@JamesMcMahon teşekkürler, benim durumum aslında kullanıcıların çerezlerini temizleyen veya çerezleri engelleyen neden olduğunu anladım. Bu sorudan yükler öğrenildi!
Ryan-Neal Mes

61

Bu hatanın çeşitli nedenleri vardır (Rails 4 ile ilgili).

1. <%= csrf_meta_tags %>Sayfa mizanpajında ​​mevcut olup

olmadığını kontrol edin 2. Option form_forile yardımcı kullanıyorsanız AJAX çağrıları ile özgünlük belirtecinin gönderildiğini kontrol edin . 3. Önbellekteki sayfadan istek gönderiliyorsa, sayfanın istek gönderen kısmını hariç tutmak için parça önbelleğe alma özelliğini kullanın, aksi takdirde simge eski / geçersiz olur.remote: true<%= hidden_field_tag :authenticity_token, form_authenticity_token %>

button_to

CSRF korumasını geçersiz kılmak konusunda isteksiz olurdum ...


csrf_meta_tags <head>? Turbolinklerle çakışmadığından nasıl emin olabilirim?
ışıltı

37

Sadece authenticity_tokenformu eklemek benim için düzeltti.

<%= hidden_field_tag :authenticity_token, form_authenticity_token %>

3
Rayların jetonu varsayılan olarak göndermesi gerekiyordu. Açıkça belirtmek istemiyoruz. Burada bu durumda jetonun bir şekilde değiştiğini hissediyorum.
Abhi

1
Ancak, formunuzu yardımcılar kullanmadan oluşturduysanız, el ile koymanız gerekir.
André Guimarães Sakata

30

Orijinallik belirteci, isteğinizin başka bir yerde değil, sitenizdeki bir formdan gönderildiğini kanıtlamak için görünümünüzde oluşturulan rastgele bir değerdir. Bu CSRF saldırılarına karşı koruma sağlar:

http://en.wikipedia.org/wiki/Cross-site_request_forgery

Bu istemcinin / IP'nin kim olduğunu kontrol edin, görünümlerinizi yüklemeden sitenizi kullanıyor gibi görünüyor.

Daha fazla hata ayıklamanız gerekirse, bu soru başlamak için iyi bir yerdir: Rails Authenticity Token'ı Anlama

Açıklamak için düzenlendi: Bu, formunuzu web sitenizde hiç görüntülemeden form gönderiminizi işleme koyma eylemini çağırdıkları anlamına gelir. Bu kötü amaçlı olabilir (spam yorum gönderme) veya web hizmeti API'nızı doğrudan kullanmaya çalışan bir müşterinin belirtisi olabilir. Bunu, ürününüzün doğası gereği ve isteklerinizi analiz ederek cevaplayabilecek tek kişisiniz.


1
Teşekkürler, ama zaten özgünlük belirtecinin ne olduğunu biliyorum. Bu istemcinin / IP'nin kim olduğunu kontrol edin, görünümlerinizi yüklemeden sitenizi kullanıyor gibi görünüyor. Maalesef, "görünüm yüklemeden" ne anlama geliyor?
Nikita Rybak

1
Birisinin (muhtemelen bir spam gönderen), uygulamanızın kullanıcı arayüzünden geçmeden formunuza veri gönderebileceği anlamına gelir. Bunu curl gibi bir komut satırı programı kullanarak yapmak mümkündür.
John Topley

John tam olarak haklı. Bu, formunuzu web sitenizde hiç görüntülemeden form gönderiminizi işlemek için harekete geçtikleri anlamına gelir. Bu kötü amaçlı olabilir (spam yorum gönderme) veya web hizmeti API'nızı doğrudan kullanmaya çalışan bir müşterinin belirtisi olabilir. Bunu, ürününüzün doğası gereği ve isteklerinizi analiz ederek cevaplayabilecek tek kişisiniz.
Winfield

Tamam, Winfield'ın yorumunu yanlış anladım. Uygulamanın, tarayıcıyı kullandığımda 'görünümlerimi yüklemek' için bir şekilde yapılandırılmadığını düşündüm.
Nikita Rybak

1
Başka bir düşüncem vardı, bu istekler bir jeton içeriyor, ancak geçerli değil. Bunun nedeni, formunuzu oluşturan sayfanın önbelleğe alınması veya potansiyel olarak formun eski bir sürümüne neden olan başka bir şey olabilir.
Winfield

28

ActionController::InvalidAuthenticityTokenyanlış yapılandırılmış bir ters proxy'den de kaynaklanabilir. Yığın izlemesinde, benzer bir çizgi alırsanız durum budur Request origin does not match request base_url.

HTTPS isteği için alıcı olarak bir ters proxy (nginx gibi) kullanıldığında ve şifrelenmemiş isteği arka uca (Rails uygulaması gibi) iletirken, arka uç (daha spesifik olarak: Raf) bazı üstbilgileri orijinal istemci isteği hakkında daha fazla bilgi ile bekler çeşitli işleme görevlerini ve güvenlik önlemlerini uygulayabilmek için.

Daha fazla ayrıntıyı burada bulabilirsiniz: https://github.com/rails/rails/issues/22965 .

TL; DR: çözüm bazı başlıklar eklemektir:

upstream myapp {
  server              unix:///path/to/puma.sock;
}

location / {
  proxy_pass        http://myapp;
  proxy_set_header  Host $host;
  proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
  proxy_set_header  X-Forwarded-Proto $scheme;
  proxy_set_header  X-Forwarded-Ssl on; # Optional
  proxy_set_header  X-Forwarded-Port $server_port;
  proxy_set_header  X-Forwarded-Host $host;
}

Vay canına, bunun için 3 saattir bir çözüm arıyordum ve bu kadar, teşekkürler!
evexoio

raylar tarafında bunu çözmeye çalışırken 6 saat çok teşekkür ederim
Joe Half Face

18

cevap vermek için çok geç ama çözümü buldum.

Kendi html formunuzu tanımladığınızda, güvenlik nedeniyle denetleyiciye gönderilmesi gereken kimlik doğrulama belirteci dizesini kaçırırsınız. Ancak bir form oluşturmak için ray form yardımcısı kullandığınızda aşağıdaki gibi bir şey elde edersiniz

<form accept-charset="UTF-8" action="/login/signin" method="post">
  <div style="display:none">
    <input name="utf8" type="hidden" value="&#x2713;">
    <input name="authenticity_token" type="hidden" 
      value="x37DrAAwyIIb7s+w2+AdoCR8cAJIpQhIetKRrPgG5VA=">
    .
    .
    .
  </div>
</form>

Bu nedenle, sorunun çözümü, authenticity_token alanı eklemek veya rayları kaldırmak, düşürmek veya yükseltmek yerine raylar form yardımcıları kullanmaktır.


9

Birinizi rake rails:updateveya yakın zamanda başka bir şeyi değiştirdiyseniz config/initializers/session_store.rb, bu tarayıcıdaki eski çerezlerin bir belirtisi olabilir. Umarım bu dev / test (benim için) yapılır ve söz konusu alanla ilgili tüm tarayıcı çerezlerini temizleyebilirsiniz.

Bu üretimde ise ve siz değiştirdiyseniz key, eski çerezleri kullanmak için tekrar değiştirmeyi düşünün (<- sadece spekülasyon).


Evet! Benim için boş bir session_store.rb olması hataya neden oluyordu.
lafeber

6

Javascript çağrıları ile bu sorunu vardı. Sadece jquery_ujs application.js dosyasına gerektiren ile düzeltildi.


Evet doğru, ben de bu sorunu vardı ve ben uygulama js jquery_ujs ekledi. İşe yaradı.
Abhi

3

Aynı sorunu yaşadık, ancak bunun https: // ile değil, yalnızca http: // kullanan istekler için olduğunu fark ettik. Nedeni secure: truesession_store içindi :

Rails.application.config.session_store(
  :cookie_store,
  key: '_foo_session',
  domain: '.example.com',
  secure: true
)

Her yerde HTTPS ~ kullanılarak düzeltildi :)


rails sGeliştirme için ayarladığım SSL uç noktası yerine (SSL olmayan) kullanırken bu sorunla karşılaştım . Yorumunuzu okuyana kadar ne yaptığımı anladım. SSL kullanmaya geri döndüğümde işler tekrar çalışmaya başladı. Teşekkürler!
Karl Wilbur

1
Bu konuyu gelişimde karşıladım. Yerine secure: trueYazdığımsecure: !Rails.env.development?
mürb

1

Raylar 5 için, atlamaktan daha iyidir protect_from_forgery prepend: true.verify_authentication_token


5
Neden? Referans ekleyebilir misiniz?
kwerle


0

Bu sorunu yaşadım ve bunun nedeni, bir denetleyiciyi kopyalayıp uygulamama yapıştırmamdı. Değiştirmek ApplicationControllerzorunda kaldımApplicationController::Base


0

Aynı sorunu localhost'ta da yaşadım. Uygulamanın alan adını değiştirdim, ancak URL'ler ve ana bilgisayarlar dosyasında hala eski alan vardı. Tarayıcı yer işaretlerimi ve ana makinelerimi yeni alan adı kullanacak şekilde güncelledi ve şimdi her şey iyi çalışıyor.


0

Belki de HTTPS için NGINX kurulumunuz var, ancak sertifikalarınız geçersiz? Geçmişte benzer bir sorun yaşadım ve http'den https'ye yönlendirme sorunu çözdü


0

<% = Csrf_meta_tags%> 'nin bulunduğunu ve tarayıcıdaki çerezleri temizlemenin benim için çalıştığını kontrol ettim.


0

Daha hızlı bir uygulama yüklemesi için Chrome Deniz Feneri önerilerini izleyerek Javascriptimi senkronize ettim:

views/layout/application.html.erb

<%= javascript_include_tag 'application', 'data-turbolinks-track' => 'reload', async: true %>

Bu, her şeyi bozdu ve uzak formlarım için Token hatasını aldı. Kaldırma async: truesorunu düzeltti.


0

Bu cevap Ruby on Rails'e çok daha özeldir, ancak umarım birine yardımcı olacaktır.

GET olmayan tüm isteklere CSRF jetonunu eklemeniz gerekir. JQuery kullanmaya alışkınsanız, Rails adlı bir yardımcı kütüphanejquery-ujs üzerine inşa edilen ve bazı gizli işlevler ekleyen . Yaptığı şeylerden biri, her ajaxtalebe otomatik olarak CSRF jetonunu eklemektir . Buraya bakın .

Benim yaptığım gibi ondan uzaklaşırsanız, kendinizi bir hata ile bulabilirsiniz. Jetonu manuel olarak gönderebilir veya jetonu DOM'dan kazımak için başka bir kütüphane kullanabilirsiniz. Daha fazla ayrıntı için bu gönderiye bakın .


0

Geliştirme ortamı için, bu sorunu düzeltmek için Rails 6'da denedim. Hiçbiri yardımcı olmadı. Dolayısıyla, bu önerilerin hiçbiri sizin için işe yaramadıysa, aşağıda deneyin.

Bulduğum tek çözüm / tmp klasörünüze bir txt dosyası eklemekti.

Uygulamanızın kök dizininde şunlardan birini çalıştırın:

touch tmp/caching-dev.txt

Veya / tmp klasörünüzde bu ada göre manuel olarak bir dosya oluşturun. Bu benim için düzelttiğinden, sorunun kökünün önbellek çatışması olduğunu varsayıyorum.


-1

Ray 5'e 2 satır kod eklememiz gerekiyor

    skip_before_action :verify_authenticity_token
    protect_from_forgery prepend: true, with: :exception

-2

yükleme

gem 'remotipart' 

yardım edebilir


3
Her ne kadar bu cevap olabilir, ama aynı zamanda cevabın temel kısmını eklemek ve neden / nasıl çalıştığını açıklamak da yararlıdır.
Roy Lee

-15

2.3.8'den 2.3.5'e düşürülerek sorun çözüldü. (aynı zamanda rezil 'Yönlendiriliyorsunuz' sorununun yanı sıra)


@Flip belki de kabul edilen cevabı güncellemek için bir fikirdir?
lafeber
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.