Matthew
Matthew

Reputation: 137

Rails Devise Authentication Token with AJAX

I'm making AJAX based application with Devise as authentication system. The problem I encountered is that when I sign in with Devise with AJAX, then when view changes and log out button appears it's showing this error when clicked:

ActionController::InvalidAuthenticityToken in Customization::SessionsController#destroy

ActionController::InvalidAuthenticityToken

Parameters:

{"_method"=>"delete",
 "authenticity_token"=>"hitX5aEjoTzi3tKP3y76+c60MuJumv5mwNEjyGUOQiY="}

Here you have my devise session controller's create method for signing in (I had to change few things to make AJAX happen):

  # POST /resource/sign_in
  def create
    self.resource = warden.authenticate!(auth_options)
    sign_in(resource_name, resource)
    yield resource if block_given?
    if user_signed_in?
      flash[:logged] = "Zalogowany"
      respond_to do |format|
        format.html { redirect_to root_path }
        format.js { render "sign_in_success.js.erb" }
      end
    end
  end

sign_in_success.js.erb file:

$("body").empty();
$("body").append("<%= j(render template: 'layouts/user') %>");

button inside "layouts/user":

a href="#{destroy_user_session_path}" data-method="delete" rel="nofollow"
  button.btn.btn-primary.m-r-20 type="button"
    b Log Out

How do I send Authenticity Token with AJAX? Can I send it to "layouts/user" via locals option in render and use it this way?

Upvotes: 1

Views: 561

Answers (1)

Matthew
Matthew

Reputation: 137

I have solution. The problem was that csrf_meta_tags, was not updated when new session was created. The solution to that problem was to include additional code inside sign_in_success.js.erb file:

$("body").empty();
$("meta[name='csrf-token']").remove()
$("meta[name='csrf-param']").remove()
$("head").append("<meta name='csrf-token' content='<%= form_authenticity_token %>'>");
$("head").append("<meta name='csrf-param' content='<%= request_forgery_protection_token %>'>");
$("body").append("<%= j(render template: 'user/logged_signed') %>");

With code seen above firstly we are empting body element , then we are removing from DOM meta tags created by csrf_meta_tags helper. After that we are manually adding new csrf-token and csrf-param, this time our new authenticity token is assigned to meta name="csrf-token".

After that when we click on our log_out button rendered by "user/logged_signed" template we are logged out successfully and back at our root_path.

Upvotes: 1

Related Questions