ActionController::InvalidAuthenticityToken in RegistrationsController#create [英] ActionController::InvalidAuthenticityToken in RegistrationsController#create

查看:19
本文介绍了ActionController::InvalidAuthenticityToken in RegistrationsController#create的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 Devise 进行用户身份验证,突然我的新用户注册不起作用.

这是我遇到的错误.

ActionController::InvalidAuthenticityTokenRails.root:/home/example/app应用程序跟踪 |框架跟踪 |完整跟踪要求参数:{utf8"=>✓","用户"=>{"email"=>"example@gmail.com",密码"=>[过滤]","password_confirmation"=>"[过滤]"},x"=>0",y"=>0"}

这是我的注册控制器

class RegistrationsController <设计::注册控制器prepend_before_filter :require_no_authentication, :only =>[ :new, :create, :cancel ]prepend_before_filter :authenticate_scope!, :only =>[:edit, :update, :destroy]before_filter :configure_permitted_pa​​rametersprepend_view_path 'app/views/devise'# 获取/resource/sign_up定义新构建资源({})response_with self.resource结尾# 发布/资源定义创建构建资源(sign_up_params)如果resource.save如果resource.active_for_authentication?set_flash_message :notice, :signed_up 如果 is_navigational_format?注册(资源名称,资源)response_with 资源,:location =>after_sign_up_path_for(资源)别的set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" 如果 is_navigational_format?expire_session_data_after_sign_in!response_with 资源,:location =>after_inactive_sign_up_path_for(资源)结尾别的clean_up_passwords 资源response_to do |格式|format.json { 渲染:json =>resource.errors, :status =>:unprocessable_entity }format.html { response_with 资源}结尾结尾结尾# 获取/资源/编辑定义编辑渲染:编辑结尾# 放置/资源# 我们需要使用资源的副本,因为我们不想改变# 当前用户就位.定义更新self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)prev_unconfirmed_email = resource.unconfirmed_email 如果 resource.respond_to?(:unconfirmed_email)如果更新资源(资源,account_update_params)如果 is_navigational_format?flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?:update_needs_confirmation :: 更新set_flash_message :通知,flash_key结尾sign_in resource_name, 资源, :bypass =>真的response_with 资源,:location =>after_update_path_for(资源)别的clean_up_passwords 资源response_with 资源结尾结尾# 删除/资源销毁资源破坏Devise.sign_out_all_scopes ?签出:签出(资源名称)set_flash_message :notice, :destroyed if is_navigational_format?response_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }结尾# 获取/资源/取消# 强制会话数据通常在签名后过期# in 现已过期.如果用户想要,这很有用# 在过程中取消 oauth 登录/注册,# 删除所有 OAuth 会话数据.取消expire_session_data_after_sign_in!重定向到新注册路径(资源名称)结尾受保护# 自定义字段def configure_permitted_pa​​rametersdevise_parameter_sanitizer.for(:sign_up) 做 |u|u.permit(:first_name, :last_name,:email, :password, :password_confirmation)结尾结尾def update_needs_confirmation?(资源,以前)resource.respond_to?(:pending_reconfirmation?) &&resource.pending_reconfirmation?&&上一个 != resource.unconfirmed_email结尾# 默认情况下,我们希望在更新时要求密码检查.# 你可以在你自己的 RegistrationsController 中覆盖这个方法.def update_resource(资源,参数)resource.update_with_password(参数)结尾# 构建一个在会话中传递的设计资源.有用的移动# 临时会话数据到新创建的用户.def build_resource(hash=nil)self.resource = resource_class.new_with_session(hash || {}, session)结尾# 在用户注册时登录.您可以自己覆盖此方法# 注册控制器.def sign_up(资源名称,资源)登录(资源名称,资源)结尾# 注册后使用的路径.您需要覆盖此方法# 在你自己的 RegistrationsController 中.def after_sign_up_path_for(资源)after_sign_in_path_for(资源)结尾# 注册非活动帐户后使用的路径.你需要覆盖# 这个方法在你自己的 RegistrationsController 中.def after_inactive_sign_up_path_for(资源)response_to?(:root_path) ?根路径:/"结尾# 更新资源后使用的默认 url.你需要覆盖# 这个方法在你自己的 RegistrationsController 中.def after_update_path_for(资源)signed_in_root_path(资源)结尾# 验证当前作用域并从会话中获取当前资源.定义身份验证范围!发送(:"authenticate_#{resource_name}!", :force => true)self.resource = send(:"current_#{resource_name}")结尾def sign_up_paramsdevise_parameter_sanitizer.sanitize(:sign_up)结尾def account_update_paramsdevise_parameter_sanitizer.sanitize(:account_update)结尾结尾

这是我的会话控制器

class SessionsController <设计控制器prepend_before_filter :require_no_authentication, :only =>[ :new, :create ]prepend_before_filter :allow_params_authentication!, :only =>:创建prepend_before_filter { request.env["devise.skip_timeout"] = true }prepend_view_path 'app/views/devise'# 获取/resource/sign_in定义新self.resource = resource_class.new(sign_in_params)clean_up_passwords(资源)响应(资源,序列化选项(资源))结尾# POST/resource/sign_in定义创建self.resource =warden.authenticate!(auth_options)set_flash_message(:notice, :signed_in) 如果 is_navigational_format?登录(资源名称,资源)response_to do |格式|format.json { 渲染:json =>{}, :status =>:行 }format.html { response_with resource, :location =>after_sign_in_path_for(资源)}结尾结尾# 删除/resource/sign_out销毁重定向路径 = after_sign_out_path_for(resource_name)signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))set_flash_message :notice, :signed_out 如果signed_out &&is_navigational_format?# 我们实际上需要对此进行硬编码,因为 Rails 默认响应器不需要# 支持GET请求返回空响应response_to do |格式|format.all { 头:no_content }format.any(*navigational_formats) { redirect_to redirect_path }结尾结尾受保护def sign_in_paramsdevise_parameter_sanitizer.sanitize(:sign_in)结尾def serialize_options(资源)方法 = resource_class.authentication_keys.dupmethods = methods.keys if methods.is_a?(Hash)方法<<:password 如果 resource.respond_to?(:password){:方法=>方法,:only =>[:密码] }结尾def auth_options{:范围=>资源名称,:召回 =>#{controller_path}#new"}结尾结尾

这是报名表

<%= form_for(:user, :html => {:id => 'register_form'}, :url => user_registration_path, :remote => :true, :format =>; :json) 做 |f|%><div class="name_input_container"><div class="name_input_cell"><%= f.email_field :email, :placeholder =>电子邮件"%><%= f.password_field :password, :placeholder =>"密码", :title =>"8+ 个字符" %><%= f.password_field :password_confirmation, :placeholder =>确认密码" %><div class="option_buttons"><div class="already_registered"><%= link_to '已经注册?', '#', :class =>'already_registered', :id =>'already_registered', :view =>'登录' %>

<%= image_submit_tag('modals/account/register_submit.png', :class => 'go') %><div class="clear"></div>

<%结束%>

解决方案

Per 核心application_controller.rb中的评论,设置protect_from_forgery如下:

protect_from_forgery with: :null_session

或者,根据文档,只需声明protect_from_forgery 没有 :with 参数 将默认使用 :null_session:

protect_from_forgery # 同上

更新:

这似乎是 Devise 行为中记录的错误.Devise 的作者建议在特定控制器操作上禁用 protect_from_forgery引发此异常:

# app/controllers/users/registrations_controller.rb类注册控制器<设计::注册控制器skip_before_filter :verify_authenticity_token, :only =>:创建结尾

Hi I am using Devise for my user authentication suddenly my new user registration was not working.

this was error I am getting.

ActionController::InvalidAuthenticityToken

Rails.root: /home/example/app
Application Trace | Framework Trace | Full Trace

Request

Parameters:

{"utf8"=>"✓",
 "user"=>{"email"=>"example@gmail.com",
 "password"=>"[FILTERED]",
 "password_confirmation"=>"[FILTERED]"},
 "x"=>"0",
 "y"=>"0"}

this is my registrations controller

class RegistrationsController < Devise::RegistrationsController
  prepend_before_filter :require_no_authentication, :only => [ :new, :create, :cancel ]
  prepend_before_filter :authenticate_scope!, :only => [:edit, :update, :destroy]

  before_filter :configure_permitted_parameters

  prepend_view_path 'app/views/devise'

  # GET /resource/sign_up
  def new
    build_resource({})
    respond_with self.resource
  end

  # POST /resource
  def create
    build_resource(sign_up_params)

    if resource.save
      if resource.active_for_authentication?
        set_flash_message :notice, :signed_up if is_navigational_format?
        sign_up(resource_name, resource)
        respond_with resource, :location => after_sign_up_path_for(resource)
      else
        set_flash_message :notice, :"signed_up_but_#{resource.inactive_message}" if is_navigational_format?
        expire_session_data_after_sign_in!
        respond_with resource, :location => after_inactive_sign_up_path_for(resource)
      end
    else
      clean_up_passwords resource

      respond_to do |format|
        format.json { render :json => resource.errors, :status => :unprocessable_entity }
        format.html { respond_with resource }
      end
    end
  end

  # GET /resource/edit
  def edit
    render :edit
  end

  # PUT /resource
  # We need to use a copy of the resource because we don't want to change
  # the current user in place.
  def update
    self.resource = resource_class.to_adapter.get!(send(:"current_#{resource_name}").to_key)
    prev_unconfirmed_email = resource.unconfirmed_email if resource.respond_to?(:unconfirmed_email)

    if update_resource(resource, account_update_params)
      if is_navigational_format?
        flash_key = update_needs_confirmation?(resource, prev_unconfirmed_email) ?
          :update_needs_confirmation : :updated
        set_flash_message :notice, flash_key
      end
      sign_in resource_name, resource, :bypass => true
      respond_with resource, :location => after_update_path_for(resource)
    else
      clean_up_passwords resource
      respond_with resource
    end
  end

  # DELETE /resource
  def destroy
    resource.destroy
    Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name)
    set_flash_message :notice, :destroyed if is_navigational_format?
    respond_with_navigational(resource){ redirect_to after_sign_out_path_for(resource_name) }
  end

  # GET /resource/cancel
  # Forces the session data which is usually expired after sign
  # in to be expired now. This is useful if the user wants to
  # cancel oauth signing in/up in the middle of the process,
  # removing all OAuth session data.
  def cancel
    expire_session_data_after_sign_in!
    redirect_to new_registration_path(resource_name)
  end

  protected

  # Custom Fields
  def configure_permitted_parameters
    devise_parameter_sanitizer.for(:sign_up) do |u|
      u.permit(:first_name, :last_name,
        :email, :password, :password_confirmation)
    end
  end

  def update_needs_confirmation?(resource, previous)
    resource.respond_to?(:pending_reconfirmation?) &&
      resource.pending_reconfirmation? &&
      previous != resource.unconfirmed_email
  end

  # By default we want to require a password checks on update.
  # You can overwrite this method in your own RegistrationsController.
  def update_resource(resource, params)
    resource.update_with_password(params)
  end

  # Build a devise resource passing in the session. Useful to move
  # temporary session data to the newly created user.
  def build_resource(hash=nil)
    self.resource = resource_class.new_with_session(hash || {}, session)
  end

  # Signs in a user on sign up. You can overwrite this method in your own
  # RegistrationsController.
  def sign_up(resource_name, resource)
    sign_in(resource_name, resource)
  end

  # The path used after sign up. You need to overwrite this method
  # in your own RegistrationsController.
  def after_sign_up_path_for(resource)
    after_sign_in_path_for(resource)
  end

  # The path used after sign up for inactive accounts. You need to overwrite
  # this method in your own RegistrationsController.
  def after_inactive_sign_up_path_for(resource)
    respond_to?(:root_path) ? root_path : "/"
  end

  # The default url to be used after updating a resource. You need to overwrite
  # this method in your own RegistrationsController.
  def after_update_path_for(resource)
    signed_in_root_path(resource)
  end

  # Authenticates the current scope and gets the current resource from the session.
  def authenticate_scope!
    send(:"authenticate_#{resource_name}!", :force => true)
    self.resource = send(:"current_#{resource_name}")
  end

  def sign_up_params
    devise_parameter_sanitizer.sanitize(:sign_up)
  end

  def account_update_params
    devise_parameter_sanitizer.sanitize(:account_update)
  end
end

and this is my sessions controller

class SessionsController < DeviseController
  prepend_before_filter :require_no_authentication, :only => [ :new, :create ]
  prepend_before_filter :allow_params_authentication!, :only => :create
  prepend_before_filter { request.env["devise.skip_timeout"] = true }

  prepend_view_path 'app/views/devise'

  # GET /resource/sign_in
  def new
    self.resource = resource_class.new(sign_in_params)
    clean_up_passwords(resource)
    respond_with(resource, serialize_options(resource))
  end

  # POST /resource/sign_in
  def create
    self.resource = warden.authenticate!(auth_options)
    set_flash_message(:notice, :signed_in) if is_navigational_format?
    sign_in(resource_name, resource)

    respond_to do |format|
        format.json { render :json => {}, :status => :ok }
        format.html { respond_with resource, :location => after_sign_in_path_for(resource) } 
    end
  end

  # DELETE /resource/sign_out
  def destroy
    redirect_path = after_sign_out_path_for(resource_name)
    signed_out = (Devise.sign_out_all_scopes ? sign_out : sign_out(resource_name))
    set_flash_message :notice, :signed_out if signed_out && is_navigational_format?

    # We actually need to hardcode this as Rails default responder doesn't
    # support returning empty response on GET request
    respond_to do |format|
      format.all { head :no_content }
      format.any(*navigational_formats) { redirect_to redirect_path }
    end
  end


  protected

  def sign_in_params
    devise_parameter_sanitizer.sanitize(:sign_in)
  end

  def serialize_options(resource)
    methods = resource_class.authentication_keys.dup
    methods = methods.keys if methods.is_a?(Hash)
    methods << :password if resource.respond_to?(:password)
    { :methods => methods, :only => [:password] }
  end

  def auth_options
    { :scope => resource_name, :recall => "#{controller_path}#new" }
  end
end

this is registration form

<%= form_for(:user, :html => {:id => 'register_form'}, :url => user_registration_path, :remote => :true, :format => :json) do |f| %>

    <div class="name_input_container">
        <div class="name_input_cell">


    <%= f.email_field :email, :placeholder => "email" %>


    <%= f.password_field :password, :placeholder => "password", :title => "8+ characters" %>


    <%= f.password_field :password_confirmation, :placeholder => "confirm password" %>


    <div class="option_buttons">
        <div class="already_registered">
            <%= link_to 'already registered?', '#', :class => 'already_registered', :id => 'already_registered', :view => 'login' %>
        </div>
        <%= image_submit_tag('modals/account/register_submit.png', :class => 'go') %>
        <div class="clear"></div>
    </div>
<% end %>

解决方案

Per the comments in the core application_controller.rb, set protect_from_forgery to the following:

protect_from_forgery with: :null_session

Alternatively, per the docs, simply declaring protect_from_forgery without a :with argument will utilize :null_session by default:

protect_from_forgery # Same as above

UPDATE:

This seems to be a documented bug in the behavior of Devise. The author of Devise suggests disabling protect_from_forgery on the particular controller action that's raising this exception:

# app/controllers/users/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
  skip_before_filter :verify_authenticity_token, :only => :create
end

这篇关于ActionController::InvalidAuthenticityToken in RegistrationsController#create的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆