天道酬勤,学无止境

未定义的方法 `authenticate_user! Devise / Rails 4 中的 Api::PostsController(undefined method `authenticate_user! Api::PostsController in Devise / Rails 4)

问题

我的项目中有以下路线:

  root 'home#index'

  namespace :api, defaults: { format: :json } do
    devise_for :users, controllers: { sessions: "api/sessions" }
    resources :posts
  end

用户模型:

class User < ActiveRecord::Base
    has_many :posts,        dependent: :destroy
    has_many :comments, dependent: :destroy

    validates :name, presence: true

    devise :database_authenticatable, :rememberable
end

会话控制器:

class Api::SessionsController < Devise::SessionsController
  def create
    @user = User.find_for_database_authentication(email: params[:user][:email])
    if @user && @user.valid_password?(params[:user][:password])
        sign_in(@user)
    else
        warden.custom_failure!
      @errors = [ 'Invalid email or password' ]
        render 'api/shared/errors', status: :unauthorized
    end
    end
end

应用控制器:

class ApplicationController < ActionController::Base
  # Prevent CSRF attacks by raising an exception.
  # For APIs, you may want to use :null_session instead.
  #protect_from_forgery with: :exception
end

最后我的 Post 控制器:

class Api::PostsController < ApplicationController
    before_action :authenticate_user!, only: [ :create ]

    def create
      current_user.posts.create!(post_params)
    end

    private

        def post_params
            params.require(:post).permit(:title, :content)
        end
end

但是当我尝试创建一个新帖子时,我收到以下错误:“未定义的方法 `authenticate_user!Api::PostsController”。 如果我删除它,我会收到关于“current_user”方法的错误。 有什么问题? 我该如何解决? 提前致谢!!!

回答1

由于在routes.rb文件的:api命名空间中嵌套设计,您会收到该错误。 因此,您应该通过以下方式对用户进行身份验证:

class Api::PostsController < ApplicationController
    before_action :authenticate_api_user!, only: [ :create ]
end
回答2

我在使用设计时遇到了类似的问题。 问题是我用不同的名称而不是用户命名我的数据库(我命名为 xuser)。 就我而言,我所要做的就是重命名控制器中的变量。 像这样的东西

before_action :authenticate_xuser!, only: [ :create ]

def create
    current_xuser.posts.create!(post_params)
end

private

def post_params
       params.require(:post).permit(:title, :content)
end

希望能帮助到你!

受限制的 HTML

  • 允许的HTML标签:<a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd> <h2 id> <h3 id> <h4 id> <h5 id> <h6 id>
  • 自动断行和分段。
  • 网页和电子邮件地址自动转换为链接。

相关推荐
  • 如果用户未通过Devise进行身份验证,则重定向到登录页面(Redirect to log in page if user is not authenticated with Devise)
    问题 我正在将Devise与Ruby on Rails一起使用。 如果未经身份验证的用户尝试访问需要身份验证的页面,建议将未身份验证的用户重定向到session#new页面的建议方法是什么? 现在,我收到一条错误消息,指出没有路由与他们尝试访问的路由匹配(导致生产中出现404错误)。 回答1 简单地将此方法添加到application_controller.rb protected def authenticate_user! if user_signed_in? super else redirect_to login_path, :notice => 'if you want to add a notice' ## if you want render 404 page ## render :file => File.join(Rails.root, 'public/404'), :formats => [:html], :status => 404, :layout => false end end 您可以在before_filter另一个所需的控制器上调用此方法。 例如: class HomesController < ApplicationController before_filter :authenticate_user! ## if you want
  • Rails + Devise:如何覆盖 before_filter “authenticate_user!”的重定向(Rails + Devise: How to override redirect for the before_filter “authenticate_user!”)
    问题 我使用的是 Rails 3 和最新版本的 Devise,我的AdminController有一个 before 过滤器来authenticate_user! 我需要在request.referrer重定向之前为它存储一个会话变量,以便我可以在他们尝试继续操作时将其发送回 /admin 页面。 我在哪里覆盖authenticate_user! ? 我想做的是这个,但我不知道在哪里定义它: def authenticate_user! session[:return_to] = request.request_uri super end 回答1 您实际上不需要这样做,设计将出于此确切目的尊重after_sign_in_path 。 在您的应用程序控制器中: before_filter :set_return_path def after_sign_in_path_for(resource) session["user_return_to"] || root_url end def set_return_path unless devise_controller? || request.xhr? || !request.get? session["user_return_to"] = request.url end end 来自设计助手: # The default url to
  • 不允许的参数将新字段添加到Rails 4.0中的Devise中(Unpermitted Parameters adding new fields to Devise in rails 4.0)
    问题 对使用Rails来说是非常新的。 我已经使用Devise实现了基本的登录系统。 我正在尝试在sign_up页面中添加几个新字段(bio:string,name:string)。 我可以正确显示所有内容,并将新字段添加到数据库中(当我在SQLbrowser中查看它时),但是它们没有填充,并且在用户提交sign_up表单后,会出现一条消息,其中部分内容为: Unpermitted parameters: bio, name 我已经将2个字符串添加到_devise_create_users.rb # added t.string :bio t.string :name 我让他们出现在schema.rb中 ActiveRecord::Schema.define(version: 20130629002343) do create_table "users", force: true do |t| t.string "email", default: "", null: false t.string "encrypted_password", default: "", null: false t.string "reset_password_token" t.datetime "reset_password_sent_at" t.datetime "remember_created
  • 未定义的方法 _path (NoMethodError)(undefined method _path (NoMethodError))
    问题 当我尝试访问包含用于创建帖子的表单的页面时,我在 Rails 应用程序中收到以下错误。 我正在尝试在他的示例应用程序中实现类似于 Michael Hartl 的 Micropost 功能的功能: NoMethodError in Home#index undefined method `posts_path' for #<#<Class:0xb5c70744>:0xb60013b8> 这是包含插入表单的代码的索引视图页面: <%= render 'shared/post_form' if user_signed_in? %> _post_form.html.erb: <%= form_for(@post) do |f| %> <%= render 'shared/error_messages', object: f.object %> <div class="field"> <%= f.text_area :content, placeholder: "Provide your network with a status update..." %> </div> <%= f.submit "Post", class: "btn btn-large btn-primary" %> <% end %> 这是家庭控制器: class HomeController <
  • 测试未通过:未定义的方法“验证!” 对于零:NilClass?(Test not passing: undefined method `authenticate!' for nil:NilClass?)
    问题 我有以下失败: Failures: 1) RelationshipsController creating a relationship with Ajax should increment the Relationship count Failure/Error: xhr :post, :create, relationship: { followed_id: other_user.id } NoMethodError: undefined method `authenticate!' for nil:NilClass # ./spec/controllers/relationships_controller_spec.rb:14:in `block (4 levels) in <top (required)>' # ./spec/controllers/relationships_controller_spec.rb:13:in `block (3 levels) in <top (required)>' 但很奇怪,如果我访问该站点,事情就会起作用(如果我单击“关注”按钮,关注followers计数器会增加: 最奇怪的是,没有任何身份验证! relationship_controller_spec.rb 中的方法: require 'spec_helper'
  • 在 rails 控制器中访问设备 current_user 变量(Access devise current_user variable in rails controller)
    问题 我有 Rails (4.0) 使用模型User运行 Devise gem (3.1.0)。 我有一个名为CollectionsController控制器,我想在这个控制器中使用 Devise 的访问器方法current_user获取当前登录的用户对象。 之后,它undefined local variable or method 'current_user' for CollectionsController:Class返回undefined local variable or method 'current_user' for CollectionsController:Class 。 最有趣的是,当我尝试在另一个控制器中执行相同操作时,例如PagesController — 一切正常! UPD:共享我的控制器的“代码”:) class CollectionsController < ActionController::Base def index @user = current_user end end current_user方法的来源是由 Devise 定义的,而不是我。 所以我不认为这是问题所在。 回答1 current_user是一种由 Devise 提供给ApplicationController的便捷方法。 您的控制器应该继承它: class
  • Rails Devise-current_user为零(Rails Devise - current_user is nil)
    问题 由于某种原因, current_user在我的nil模型控制器( Subscriptions )中返回nil 。 我在互联网上找不到任何可以证明这种行为的理由... class SubscriptionsController < ApplicationController def new ... end def create current_user # returns nil end end 我有一个csrf元标记: <meta content="xxx" name="csrf-token"> 我可以提供更多代码,但是我不确定什么会有用。 更新 因此,由于有了评论/回答,我将问题定位到了一个特定的动作: create 。 如果将@user = current_user添加到new ,则可以在new视图中显示当前用户的电子邮件。 但是,在我的create控制器中, current_user返回nil 。 我通过表单(提交)访问了create操作。 在提交表单之前,我将验证输入,然后向Stripe发送请求以从表单中获取令牌。 如果没有错误(验证和分条),则发送表格。 那可能是原因吗? 更新2 在我的错误消息中,我的会话转储为空,而其中应包含current_user信息... 回答1 原来我提出的AJAX请求没有携带CSRF令牌。 因此,Rails终止了我的会话。
  • 如何在AJAX中优雅地处理devise的401状态?(How can I elegantly handle devise's 401 status in AJAX?)
    问题 设计一个使用before_filter :authenticate_user! 限制只有经过身份验证的用户才能访问。 无论如何,当未经身份验证的用户尝试访问受限页面时,devise会自动导致重定向到登录页面。 因此,尝试打开 http://localhost:3000/users/edit 将导致重定向到 http://localhost:3000/users/sign_in。 现在,如果我将链接http:// localhost:3000 / users / edit定义为:remote => true ,则devise将仅通过JS发出401状态代码。 我如何优雅地应对这种情况并在覆盖或重定向中显示登录对话框,因为非远程变体会这样做? 对于我只需要激活的情况,designes是否提供了默认策略? 回答1 $(document).ajaxError(function (e, xhr, settings) { if (xhr.status == 401) { $('.selector').html(xhr.responseText); } }); 回答2 这是我现在选择的解决方案(使用CoffeeScript语法): $ -> $("a").bind "ajax:error", (event, jqXHR, ajaxSettings, thrownError) -> if
  • undefined method `authenticate_user! Api::PostsController in Devise / Rails 4
    There is the following routes in my project: root 'home#index' namespace :api, defaults: { format: :json } do devise_for :users, controllers: { sessions: "api/sessions" } resources :posts end User model: class User < ActiveRecord::Base has_many :posts, dependent: :destroy has_many :comments, dependent: :destroy validates :name, presence: true devise :database_authenticatable, :rememberable end Session controller: class Api::SessionsController < Devise::SessionsController def create @user = User.find_for_database_authentication(email: params[:user][:email]) if @user && @user.valid_password
  • 使用设计 before_action :authenticate_user! 什么都不做(Using Devise before_action :authenticate_user! doesn't do anything)
    问题 我试图要求登录我的 Rails 4 网站上的所有页面。 在 ApplicationController 中,我添加了before_action :authenticate_user! ,但它根本没有做任何事情。 我试图添加相同的before_action :authenticate_user! 到另一个控制器,它工作正常。 我是否需要对 ApplicationController 执行其他操作,以使所有操作(注册/登录除外)都需要登录? 回答1 这是我们使用的实际代码: #app/controllers/application_controller.rb Class ApplicationController < ActionController::Base #Actions before_action :authenticate_user! #-> routes to the login / signup if not authenticated end 您可能遇到的问题有两个: —— 确保您的其他控制器继承自application_controller : #app/controllers/other_controller.rb Class OtherController < ApplicationController ... end —— 你不知何故“跳过
  • 设计-无法在Rails视图中显示登录或注销(devise - can't display sign in or sign out in rails view)
    问题 我现在正在使用devise进行基本身份验证。 当我转到localhost:3000/users/sign_in我将能够登录,或者如果我登录后进入那里,我将收到相应的消息“您已经登录”。 但是, user_signed_in? 即使成功登录后也总是评估为false <div id="user_nav"> <% if user_signed_in? %> Welcome <%= current_user.email %>! <%= link_to "Sign out", destroy_user_session_path, :method => :delete %> <% else %> <%= link_to "Connect With Facebook", "/auth/facebook" %> <%= link_to "Sign out", destroy_user_session_path, :method => :delete %> <% end %> </div> <% flash.each do |name, msg| %> <%= content_tag :div, msg, :id => "flash_#{name}" %> <% end %> </div> 这是config/application.rb class ApplicationController
  • Rails API和本机移动应用程序身份验证(Rails api and native mobile app authentication)
    问题 我知道有关此主题的信息很多,但是找不到最新的信息。 我看到了与Rails和android身份验证相关的主题,但我发现TokenAuthenticatable已从设计中删除。 我的问题很简单:使用Rails 4,有没有很好的方法可以从本地Android和iPhone应用程序对用户进行身份验证? 有谁知道提供解决方案的优秀教程或文章? 亚当·韦特(Adam Waite)添加赏金: 我刚刚在这个问题上悬赏500英镑,因为我找不到在任何地方从iOS应用程序向Rails API进行身份验证的正确做法。 这是我正在考虑做的事情,但不知道它是否安全?!: 假设我们有一个User记录。 用户已经注册了一个帐户,该帐户已在数据库中创建了带有email列和password_digest列的User记录。 用户登录后,我希望该用户在移动应用上保持身份验证,直到明确退出为止。 我想我们将需要基于令牌的身份验证。 我可能会在创建User时创建一个ApiKey记录,并将其另存为User记录上的关联。 当用户登录/登录时,响应将包含一个API令牌(类似于SecureRandom.hex ),该令牌将保存在iOS钥匙串中,并与所有后续请求一起使用,以通过将其传递到标头并使用进行验证来验证用户就像是: before_filter :restrict_access private def restrict
  • 我如何指定before_filters?(How can I spec before_filters?)
    问题 我想用rspec指定我的控制器before_filter。 我想为它使用ActionController :: Testing :: ClassMethods#before_filters。 我在我的轨道上得到了这些结果c: 2.0.0p353 :006 > ActionController::Base.singleton_class.send :include, ActionController::Testing::ClassMethods 2.0.0p353 :003 > EquipmentController.before_filters => [:process_action,:process_action] 但实际上,这是我的操作的过滤条件: class EquipmentController < ApplicationController before_filter :authenticate_user! 有任何想法吗? 回答1 这是我在项目中所做的: # spec/support/matchers/have_filters.rb RSpec::Matchers.define :have_filters do |kind, *names| match do |controller| filters = controller._process_action
  • 使用API​​密钥时如何跳过Devise身份验证?(How to skip Devise authentication when using an API key?)
    问题 我在应用程序上使用Devise,并希望创建一个全局API密钥,该密钥可以访问任何人的帐户的JSON数据而无需登录。 例如,假设我的API密钥为1234并且我有两个用户创建了两个不同的餐厅。 使用者1-餐厅1(/餐厅/ 1) 使用者2-餐厅2(/ restaurants / 2) 而且我打开了一个全新的浏览器,但没有登录任何内容,而是将其传递给我的URL .../restaurants/2.json?api_key=1234 ,我应该能够访问该餐厅的JSON数据而不必登录-以用户2身份输入 最好的方法是什么? 我遵循了Railscast#352保护API的安全性,因此我可以通过传递API密钥来访问JSON内容,但是我必须登录才能看到任何内容。 编辑1:使用CanCan 我应该提到,我也使用CanCan担任角色,但不确定在这种情况下是否会扮演任何角色(双关语意)。 编辑2:使用API​​版本控制实施 我遵循了Railscast#350和#352,它们教您如何创建REST API版本控制以及如何使用API​​密钥保护它。 这是我的controllers / api / v1 / restaurants / restaurants_controller.rb的样子: module Api module V1 class RestaurantsController <
  • 如何在设计authenticate_user中删除html重定向(How to remove html redirection in devise authenticate_user)
    问题 我使用设备的authenticate_user! 控制器中的方法。 当请求中提供的auth_token是正确的时,此方法工作正常,但如果身份验证失败,我将得到以下结果: curl -XGET 'http://localhost:3000/my_obj?auth_token=wrongtoken' <html><body>You are being <a href="http://localhost:3000/users/sign_in">redirected</a>.</body></html> 当我使用rabl时,什么是最好的方式是 {'error' : 'authentication error'} 返回html重定向的intead吗? 回答1 我这样做是为了避免使用:format =>:json响应的过滤器,如果没有current_user通过,请做我自己的过滤器以呈现我的JSON响应 class MyController < ApplicationController before_filter :authenticate_user!, :unless => { request.format == :json } before_filter :user_needed, :if => { request.format == :json } def user_needed
  • 闲置/闲置后自动注销(automatic logout after inactivity/idle)
    问题 如何在Rails应用程序中设置,如果有任何用户闲置30分钟或特定时间段,则应自动将其注销。 任何人都可以提出任何解决方案。 我正在使用dev进行身份验证。 任何帮助表示赞赏。 回答1 您应该使用Timeoutable模型特征。 Timeoutable可以解决用户会话是否已经过期的问题。 当会话在配置的时间后到期时,将再次要求用户提供凭据,这意味着,他/她将被重定向到登录页面。 选项 Timeoutable将以下选项添加到devise_for: + timeout_in +:不活动的情况下使用户会话超时的时间间隔。 在您的模型中,您需要 devise :timeoutable # along with :database_authenticatable, :registerable and other things. 另外,看看config/initializers/devise.rb ,您可以在那里配置超时值。 回答2 我知道这个问题已经得到了回答,但是我想我也会提供解决方案,因为就我而言,我正在寻找比Devise的超时功能还无法提供的更多功能。 非常感谢@Sergio Tulentsev在他的回答的评论部分为我提供了有用的解释和想法! 问题 由于Devise在服务器端而不是客户端上运行,因此当身份验证令牌超时时,客户端直到用户执行调用Rails控制器的操作才知道超时。
  • 这个Rails JSON身份验证API(使用Devise)是否安全?(Is this Rails JSON authentication API (using Devise) secure?)
    问题 我的Rails应用程序使用Devise进行身份验证。 它有一个姐妹iOS应用程序,用户可以使用与Web应用程序相同的凭据登录到iOS应用程序。 因此,我需要某种API进行身份验证。 这里有许多类似的问题指向本教程,但它似乎已过时,因为从Devise中删除了token_authenticatable模块,并且其中一些行引发了错误。 (我使用的是Devise 3.2.2。)我曾尝试根据该教程(和本教程)推出自己的教程,但我对此没有100%的信心-我觉得可能有些东西被误解或错过。 首先,根据要点的建议,我向我的users表添加了authentication_token文本属性,并向user.rb了以下内容: before_save :ensure_authentication_token def ensure_authentication_token if authentication_token.blank? self.authentication_token = generate_authentication_token end end private def generate_authentication_token loop do token = Devise.friendly_token break token unless User.find_by
  • Rails:仅允许管理员用户在具有Devise的Rails中创建新用户(无外部模块)(Rails: Only allow admin user to create new users in Rails with Devise (No external modules))
    问题 当前,我的用户数据库有一个名为“ admin”的列,其值为布尔值,默认设置为false。 我有一个管理员用户植入了数据库。 如何写我的应用程序那么,谁是管理员可以创建新用户是用户,但谁不是用户不能? (此外,用户只能由管理员创建) 似乎应该有一种简单的方法来设计该方法,而不涉及使用某些外部模块。 但是到目前为止,我还没有找到满意的答案。 我将更可能标记仅设计的解决方案。 (这只是一个简单的标准MVC / Rails解决方案,另加一个)但是,如果确实有一种更好的方法不涉及CanCan,我接受。 笔记: 我一直在搜索一会儿,我发现了其他一些与此问题非常相似的stackoverflow问题,但是要么没有完全回答这个问题,要么使用了其他非设计模块。 (或两者) 回答1 要实现授权,请在控制器上使用一种方法 完全由@ diego.greyrobot建议 class UsersController < ApplicationController before_filter :authorize_admin, only: :create def create # admins only end private # This should probably be abstracted to ApplicationController # as shown by diego.greyrobot
  • Rails 5,#的未定义方法“ for”(Rails 5, Undefined method `for' for #<Devise on line devise_parameter_sanitizer.for)
    问题 我正在使用Rails 5 我在模型用户中添加了新的字段用户名。 class Users::RegistrationsController < Devise::RegistrationsController before_action :configure_permitted_parameters protected def configure_permitted_parameters devise_parameter_sanitizer.for(:sign_up).push(:username) end end 注册期间显示错误: #的未定义方法“ for”,是您的意思吗? 叉 痕迹: NoMethodError(#的未定义方法“ for”是您的意思吗?fork): app/controllers/users/registrations_controller.rb:7:in `configure_permitted_parameters' Rendering /usr/local/rvm/gems/ruby-2.3.0/gems/actionpack-5.0.0.rc1/lib/action_dispatch/middleware/templates/rescues/diagnostics.html.erb within rescues/layout Rendering
  • Rails + Devise: How to override redirect for the before_filter “authenticate_user!”
    I am on Rails 3 and the latest version of Devise, and I have a before filter in my AdminController to authenticate_user! I need to store a session variable for the request.referrer before it redirects so that I can send it back to the /admin page when they try to go on it. Where would I overwrite authenticate_user!? What I want to do is this, but I don't know where to define it: def authenticate_user! session[:return_to] = request.request_uri super end