私の場合、ユーザーをログインした後、ユーザーのメニューを再描画する必要がありました。それはうまくいきましたが、サーバーへのすべてのリクエストで、同じセクションでCSRF認証エラーが発生しました(もちろん、ページを更新しませんでした)。js ビューをレンダリングする必要があったため、上記のソリューションは機能しませんでした。
私がしたことは、Deviseを使用してこれです:
アプリ/コントローラー/sessions_controller.rb
class SessionsController < Devise::SessionsController
respond_to :json
# GET /resource/sign_in
def new
self.resource = resource_class.new(sign_in_params)
clean_up_passwords(resource)
yield resource if block_given?
if request.format.json?
markup = render_to_string :template => "devise/sessions/popup_login", :layout => false
render :json => { :data => markup }.to_json
else
respond_with(resource, serialize_options(resource))
end
end
# POST /resource/sign_in
def create
if request.format.json?
self.resource = warden.authenticate(auth_options)
if resource.nil?
return render json: {status: 'error', message: 'invalid username or password'}
end
sign_in(resource_name, resource)
render json: {status: 'success', message: '¡User authenticated!'}
else
self.resource = warden.authenticate!(auth_options)
set_flash_message(:notice, :signed_in)
sign_in(resource_name, resource)
yield resource if block_given?
respond_with resource, location: after_sign_in_path_for(resource)
end
end
end
その後、メニューを再描画するコントローラー#アクションにリクエストを行いました。そして、javascript で、X-CSRF-Param と X-CSRF-Token を変更しました。
アプリ/ビュー/ユーティリティ/redraw_user_menu.js.erb
$('.js-user-menu').html('');
$('.js-user-menu').append('<%= escape_javascript(render partial: 'shared/user_name_and_icon') %>');
$('meta[name="csrf-param"]').attr('content', '<%= request_forgery_protection_token.to_s %>');
$('meta[name="csrf-token"]').attr('content', '<%= form_authenticity_token %>');
同じjsの状況にある誰かに役立つことを願っています:)