Form_with kullanılırken "ActionController :: InvalidAuthenticityToken" hatası
Ş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
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 .
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