Form_with kullanılırken "ActionController :: InvalidAuthenticityToken" hatası

Sep 16 2020

Şuna benzeyen bir formum var:

  <%= form_with(url: star.starname, method: :post, local: true) do |f| %> 
    <% star.availabilities.each do |avail| %> 

    <%= f.label avail.time_slot %> 
      <%= radio_button_tag(:time_slot, avail.time_slot) %> <br>
    <% end %> 

  <%= f.submit "Create" %>
  <% end %> 

Form gönderildikten hemen sonra:

Notlar:

  • Bu, bir uygulamada (bir API'de değil) meydana gelir, bu nedenle oturumlar önemlidir, bu nedenle CSRF korumasının açık bırakılması gerekir.
  • Sorun krom, gizli mod ve safaride ortaya çıkıyor.
  • Farklı kullanıcılarla oturum açmayı ve çerezleri temizlemeyi denedim ( eski bir belirtecin neden olması durumunda )

Hata mesajının bir kısmı daha:

Started POST "/talljohn" for ::1 at 2020-09-16 10:06:21 +1000
Processing by StarsController#book as HTML
  Parameters: {"authenticity_token"=>"P++4a+giwUBqZgCLfMwqKpMu0EGitd8zTOi5RWsnxpKlNcjiuU6hd3ebbIC/IOxlL74RJIvrq+yDuA1ZtfcvFw==", "time_slot"=>"2020-09-16 01:00:00 UTC", "commit"=>"Create", "starname"=>"talljohn"}
Can't verify CSRF token authenticity.
Completed 422 Unprocessable Entity in 1ms (ActiveRecord: 0.0ms | Allocations: 655)


  
ActionController::InvalidAuthenticityToken (ActionController::InvalidAuthenticityToken):
  
actionpack (6.0.3.2) lib/action_controller/metal/request_forgery_protection.rb:215:in `handle_unverified_request'
actionpack (6.0.3.2) lib/action_controller/metal/request_forgery_protection.rb:247:in `handle_unverified_request'
devise (4.7.2) lib/devise/controllers/helpers.rb:255:in `handle_unverified_request'
actionpack (6.0.3.2) lib/action_controller/metal/request_forgery_protection.rb:242:in `verify_authenticity_token'
activesupport (6.0.3.2) lib/active_support/callbacks.rb:428:in `block in make_lambda'
activesupport (6.0.3.2) lib/active_support/callbacks.rb:200:in `block (2 levels) in halting'
actionpack (6.0.3.2) lib/abstract_controller/callbacks.rb:34:in `block (2 levels) in <module:Callbacks>'
activesupport (6.0.3.2) lib/active_support/callbacks.rb:201:in `block in halting'

Güncelleme

Formun son çalışan versiyonuna geri döndüm, bu tam olarak yukarıdakiyle aynı, ancak olmadan , local: true. Sonra aniden işe yarıyor! (hata yok).

local: true(Veya remote: false) ajax form gönderimini kapattığını düşündüm . Bu yüzden bunun neden herhangi bir fark yaratacağını (veya CSRF ile bir ilgisi olduğunu) anlamıyorum, bu iki yönün ilgisiz olduğu ve bu iki kavramın birbirini neden etkileyeceği açık değil.

Güncelleme 2

Daha sonra, daha önce çalışan başka bir el değmemiş formun da bu hatayı ürettiğini fark ettim. Hiçbir şekilde değiştirilmemişti. Chrome'u gizli modda denedim ve hata verdi. Yarım saat sonra (herhangi bir kodu değiştirmeden) aynı tarayıcıda tekrar denedim ve işe yaradı. Bu (çok) garip davranış, bunun oturumlar, çerezler veya önbelleğe alma ile ilgili bir şey olduğunu düşünmeme neden oluyor. Daha fazla bir şey öğrenirsem rapor edeceğim

Güncelleme 3

Sarah'ınprotect_from_forgery prepend: true uygulama denetleyicisine eklenen çözümünü okuduktan sonra (hem önce hem sonra denedim before_action :authenticate_user!), günlüklerde aynı hata mesajı görünüyor, POST isteği işleme alınmıyor, ancak uygulama ana sayfaya yönlendiriyor. Yani POST üzerine şunu görüyorum:

Can't verify CSRF token authenticity.
Completed 401 Unauthorized in 1ms (ActiveRecord: 0.0ms | Allocations: 444)


Started GET "/users/sign_in" for ::1 at 2020-09-17 21:08:42 +1000
Processing by Devise::SessionsController#new as HTML
  User Load (0.5ms)  SELECT "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 1], ["LIMIT", 1]]
Redirected to http://localhost:3000/
Filter chain halted as :require_no_authentication rendered or redirected
Completed 302 Found in 3ms (ActiveRecord: 0.5ms | Allocations: 1900)

Güncelleme 4

Ray parçası önbelleğini (ile Rails.cache.clear ) manuel olarak temizlemeye çalıştım . Ancak sonuç, parça önbelleğini temizlemeden önce / sonra tamamen aynıdır.

Yanıtlar

2 SarahMarie Sep 17 2020 at 06:46

Bunun gibi bir şeyle protect_from_forgery prepend: truekarşılaştığımı ve ApplicationControllerçözülen herhangi bir kullanıcı kimlik doğrulamasından önce eklediğimi hatırlıyorum .

1 stevec Sep 17 2020 at 20:18

TL; DR: 2 haftalık hata ayıklama girişimlerinden sonra, turbolink'leri kapattım ve sorun ortadan kalktı .

Turbolink'leri kapatmanın yanı sıra, bunu ekleyen başka bir çözüm ( burada bahsedilmiştir ) görünüyor .application.js

$(document).on('turbolinks:load', function(){ $.rails.refreshCSRFTokens(); });

Önceki cevap

Sorun yeniden ortaya çıkmaya devam etti. Aşağıdaki altı şeyi denedim ama hala düzeltmedi

1. Parça önbelleğini temizleyin

Rails.cache.clear( uyarı önbelleği temizlediği için, sidekiq işleri gibi şeyleri de kaldıracaktır). Bu, eski belirteci kaldıracak ve tarayıcıda uygulamayı yenilemek her şeyi normale döndürür ve form gönderilmelidir (basit bir 'yeniden gönderme' çalışmaz, bu nedenle form sayfasına geri dönün, yenileyin, sonra gönderin ve iş)

2. Sabit yenileme sayfası

Geliştirici konsolunu açmak için cmd+ opt+ tuşlarına basın j, ardından yenilemeye sağ tıklayın ve 'Önbelleği Boşalt ve Sabit Yeniden Yükleme'yi seçin.

3. Site çerezlerini silin

Url'nin hemen solundaki küçük simgeye sağ tıklayın (https kullanılıyorsa bir kilit, http kullanıyorsanız 'i' harfi olacaktır). Listelenen kategorilerin her birine gidin (ör. 'Çerezler', 'Site Ayarları' vb.) Ve hepsini silin

4. Aynı siteyi gösteren diğer url'ler için çerezleri silin

Örneğin, siteniz ise www.example.comve adresinde heroku'da barındırılıyorsa, www.example.herokuapp.como ikinci url için çerezleri de silin.

5. localhost için çerezleri silin

Emin olmak için localhost çerezlerini sildim

6. Chrome'un tamamen yalıtılmış örneklerinde test etme