Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issue with csrf token expired after remote form submit #484

Open
Chocksy opened this issue Feb 9, 2017 · 0 comments
Open

Issue with csrf token expired after remote form submit #484

Chocksy opened this issue Feb 9, 2017 · 0 comments

Comments

@Chocksy
Copy link

Chocksy commented Feb 9, 2017

I have an issue with the csrf token being expired when submitting a remote form. Here is the code i'm using:

= simple_form_for :user, url: login_path, remote: true, :html=> { class: 'margin-bottom-15' } do |f|
  = f.input :email, wrapper: :vertical_input_group, required: true do
    = f.email_field :email, class: "form-control", placeholder: 'Enter your email address'
  = f.input :password, wrapper: :vertical_input_group, required: true do
    = f.password_field :password, class: "form-control", placeholder: 'Enter your password'
  .row
    .col-md-12
      button.btn.btn-special.btn-success.btn-block.btn-lg type="submit"  Sign In

This forms submits the data and then i return in a flash a message plus a link with the method post:

link = view_context.link_to 'Resend confirmation email', resend_confirmation_url(email: user_params[:email]), method: :post if user_params[:email].present?
flash[:alert] = "Your credentials are wrong or your email is not confirmed. #{link}".html_safe

The link is displayed in the page and then when the user clicks that the link uses the old meta authenticity token so i get an invalid exception.

The application.html file looks ~ like this:

doctype html
html lang="en" 
  head
    = display_meta_tags
    / add custom header elements with this
    = yield(:head)
    = stylesheet_link_tag  'application', media: 'all', 'data-turbolinks-track' => true
    = csrf_meta_tags

  body class="#{@body_class}"
    .global-wrapper
      .container
        / show errors in the page or info
        .unobtrusive-flash-container

      .container.content-container
        = yield
    = javascript_include_tag 'application', 'data-turbolinks-eval' => false

The application.js file:

//= require jquery
//= require jquery.turbolinks
//= require jquery_ujs
//= require turbolinks

//= require unobtrusive_flash
//= require unobtrusive_flash_bootstrap

//= require_tree ./components
//= require_tree ./pages
//= require pxls

I'm using:

...
    turbolinks (5.0.1)
      turbolinks-source (~> 5)
...
    rails (4.2.7.1)
      actionmailer (= 4.2.7.1)

The solution i'm using currently to fix this is:

# in application_controller.rb

  # callback to set CSRF TOKEN for non-idempotent ajax request
  after_action :add_csrf_token_to_json_request_header

  private

  def add_csrf_token_to_json_request_header
    if request.xhr? && !request.get? && protect_against_forgery?
      response.headers['X-CSRF-Token'] = form_authenticity_token
    end
  end
// in my js file
      $( document ).ajaxComplete(function( event, xhr, settings ) {
        header_token = xhr.getResponseHeader('X-CSRF-Token');
        csrfToken
        if (header_token) $('meta[name=csrf-token]').attr('content', header_token)
      });
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant