I'm using Devise in a ruby-on-rails project, and before_filter :authenticate_user!, :only => [:show] is not working when I use it in UsersController :
# ./controllers/users_controller.rb
class UsersController < Devise::SessionsController
before_filter :authenticate_user!, :only => [:show]
def show
end
end
# ./config/routes.rb
Notify::Application.routes.draw do
devise_for :users
...
end
Related
I am writing a redmine plugin and need to add some actions to before_filter that is already defined in redmine's 'IssuesController'
For example,
issues_controller.rb
class IssuesController < ApplicationController
before_filter :find_issue, :only => [:show, :edit, :update]
before_filter :find_issues, :only => [:bulk_edit, :bulk_update, :destroy]
before_filter :find_project, :only => [:new, :create, :update_form]
before_filter :authorize, :except => [:index]
end
I want to add more actions to filters find_issue and find_project
So, in my plugin i'm gonna write a module and include it in IssuesController
issues_controller_patch.rb
module IssuesControllerPatch
def self.included(base) # :nodoc:
base.send(:include, InstanceMethods)
base.class_eval do
before_filter :find_issue, :only => [:new_action1, :new_action2]
before_filter :find_project, :only => [:new_action1, :new_action2]
#prepend_before_filter :find_issue, :only => [:new_action1, :new_action2]
#prepend_before_filter :find_project, :only => [:new_action1, :new_action2]
end
end
module InstanceMethods
end
end
unless IssuesController.included_modules.include?(IssuesControllerPatch)
IssuesController.send(:include, IssuesControllerPatch)
end
This is not working for me, because it's putting it on the bottom of filters chain and authorize action is executed and authorization is because authorization depends on project.
I also tried to use prepend_before_filter and it's also not working because it's putting it on the top of filters chain, even before the user loads from session.
So, how can I update action list for filters defined in IssuesController?
Rails 3.2, Ruby 1.9.3, Redmine 2.6
Is it possible that i not only define an action for before_filter but also the controller of the action? I want to put the before_filter method into my application_controller but when i define there for example:
before_filter :authorize, except: [:index]
All controllers are affected that have an index action!
I would like to wirte something like that:
before_filter :authorize, except: [user#index]
Thanks
You cannot do what you are asking for. What you can do is
class ApplicationController < ActionController::Base
before_filter :authorize
...
end
class UsersController < ApplicationController
skip_before_filter :authorize, :only => [:index]
...
end
Why not put the before filter in your users_controller?
class UsersController < ApplicationController
before_filter :authorize, except: [:index]
...
end
I'm using Devise as authenticating solution in Rails and I have a cached fragment :recent_users.
I want this fragment to expire when a new user is registered, changed or removed, so I put in my(manually created) users_controller.rb
class UsersController < ApplicationController
cache_sweeper :user_sweeper, :only => [:create, :update, :destroy]
...
But my fragment does not expire when new creates or changes.
My user_sweeper contains basic prescriptions
class UserSweeper < ActionController::Caching::Sweeper
observe User
def after_save(user)
expire_cache(user)
end
def after_destroy(user)
expire_cache(user)
end
private
def expire_cache(user)
expire_fragment :recent_users
end
end
What am I doing wrong?
Problem solved!
I followed this steps and everything works:
$ mkdir app/controllers/users
$ touch app/controllers/users/registrations_controller.rb
In registrations_controller.rb
class Users::RegistrationsController < Devise::RegistrationsController
cache_sweeper :user_sweeper, :only => [:create, :update, :destroy]
end
Problem was that Registrations in Devise is a separate controller.
Put this in applications_controller.rb
class ApplicationController < ActionController::Base
cache_sweeper :user_sweeper, :only => [:create, :update, :destroy]
...
When I have a specific action that I don't want to check the authenticity token on, how do I tell Rails to skip checking it?
Rails 5.2+
You can use the same skip_before_action method listed below or a new method skip_forgery_protection which is a thin wrapper for skip_before_action :verify_authenticity_token
skip_forgery_protection
Rails 4+:
# entire controller
skip_before_action :verify_authenticity_token
# all actions except for :create, :update, :destroy
skip_before_action :verify_authenticity_token, except: [:create, :destroy]
# only specified actions - :create, :update, :destroy
skip_before_action :verify_authenticity_token, only: [:create, :destroy]
See all options # api.rubyonrails.org
Rails 3 and below:
skip_before_filter :verify_authenticity_token
In Rails4 you use skip_before_action with except or only.
class UsersController < ApplicationController
skip_before_action :verify_authenticity_token, only: [:create]
skip_before_action :some_custom_action, except: [:new]
def new
# code
end
def create
# code
end
protected
def some_custom_action
# code
end
end
I'm creating a rails app that includes devise.
I'm trying to add Twilio messaging to my site with Ngrok, i used this tutorial:
https://www.twilio.com/blog/2016/04/receive-and-reply-to-sms-in-rails.html
I was able to open Ngrok in the console and get the web-id they give for my url.
I keep getting this error when I plug the url into my browser ..I'm supposed to get to my own rails local app. Not sure whats wrong.
What I added in my messaging controller made for ngrok:
class MessagesController < ApplicationController
skip_before_filter :verify_authenticity_token
skip_before_filter :authenticate_user!, :only => "reply"
def reply
message_body = params["Body"]
from_number = params["From"]
boot_twilio
sms = #client.messages.create(
from: Rails.application.secrets.twilio_number,
to: from_number,
body: "Hello there, thanks for texting me. Your number is #{from_number}."
)
#twilio expects a HTTP response to this request
end
private
def boot_twilio
account_sid = Rails.application.secrets.twilio_sid
auth_token = Rails.application.secrets.twilio_token
#client = Twilio::REST::Client.new account_sid, auth_token
end
end
really unsure what is wrong.
when its not connecting to the 'def reply' and authenticate_user should be defined by devise.
Twilio developer evangelist here.
It looks like this was a problem that Rails 5 seems to have introduced. If the filter hasn't been defined by the time it is used in a controller it will raise an error. This was discovered in the Clearance project too.
Their fix was to pass the raise: false option to skip_before_filter:
class MessagesController < ApplicationController
skip_before_filter :verify_authenticity_token
skip_before_filter :authenticate_user!, :only => "reply", :raise => false
end
I had a similar issue to this when I was working on a Rails 6 application with Devise gem for authentication and authorization.
I added a skip_before_action :authenticate_admin!, only: [:index, :show] to the Products controller
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
skip_before_action :authenticate_admin!, only: [:index, :show]
def index
#products = Product.all
end
.
.
.
end
And it was throwing the error below when I visit the Products page:
Before process_action callback :authenticate_admin! has not been defined
Here's how I fixed it:
To use the skip_before_action :authenticate_admin!, only: [:index, :show] in the Products controller, I first needed to define the before_action :authenticate_user! in the application_controller:
# app/controllers/application_controller.rb:
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :authenticate_admin!
end
Now I can use the skip_before_action :authenticate_admin!, only: [:index, :show] in the Products controller:
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
skip_before_action :authenticate_admin!, only: [:index, :show]
def index
#products = Product.all
end
.
.
.
end
An alternative, if I don't want to define the before_action :authenticate_user! in the application_controller is to use the before_action :authenticate_admin!, except: [:index, :show]:
class ProductsController < ApplicationController
before_action :set_product, only: [:show, :edit, :update, :destroy]
before_action :authenticate_admin!, except: [:index, :show]
def index
#products = Product.all
end
.
.
.
end
That's all.
I hope this helps