devise skip authentication based on route - ruby-on-rails

Having devise_for :users makes all methods of Users controller authenticated by Devise. I'd like to skip a couple of methods e.g users#api, users#do_stuff for making a public API with self-written auth method.
How can I do it?
UPDATE.
skip_before_filter :authenticate_user!, only: [:api, :do_stuff]
still gives me {"error":"You need to sign in or sign up before continuing."}

Try this -
skip_before_filter :authenticate_user!, :only => [:api,:do_stuff]

inside users_controller.rb...add the below lines
before_action :authenticate_user!, :only => [:api, :do_stuff]
i assume that you only want to authenticate on this two method calls in users_controller and not have added any authentication filter in application_controller.

Related

How to prevent unauthorized users from registering in Devise?

I want to allow authorized users to create (and destroy) user accounts. I have gotten this part working according to hints I found in this and other questions.
But I also want to prevent unauthorized users from creating and destroying accounts.
I have my own registration_controller:
class RegistrationsController < Devise::RegistrationsController
skip_before_action :require_no_authentication, only: [:new, :create, :destroy]
skip_before_action :authenticate_scope!, only: [:destroy]
before_action :authenticate_user!, only: [:new, :create, :destroy] # why doesn't this work?
def new
super
end
def sign_up(resource_name, resource)
# don't sign in as the new user
end
def destroy
User.find(params[:id]).destroy
redirect_to(users_path)
end
end
And have directed my routes to use it in routes.rb:
# Standard devise setup but allow registration when logged in
# https://stackoverflow.com/a/31946248/1404185
devise_for :users, controllers: {:registrations => "registrations"}
# Work around already-existing session controller
# https://stackoverflow.com/a/21024350/1404185
devise_scope :user do
post '/sessions/user', to: 'devise/sessions#create', via: :post
delete '/users/:id', to: 'registrations#destroy', via: :delete
end
# Show and index for users
# https://stackoverflow.com/a/32056094/1404185
resources :users, :only => [:show,:index]
For some reason before_action :authenticate_user! does not work... unauthenticated users can still invoke these actions. I've also tried prepend_before_action :authenticate_user!, and I've tried putting the filters in different orders-- invoking the before_action first in my controller.
I've just upgraded my app to rails 6.0.3.5 and added devise 4.7.1.
Why do I want this unusual setup? This is a hobby project and only my girlfriend and I are users. We don't want just anybody on the internet to sign up. But we occasionally may want to give another person access, who will be sitting next to us (pandemic permitting) when creating their account.
I do have a workaround for now: Since the site will have an obfuscated URL and since it is an extremely low value target (I can't imagine anyone would be interested in our home inventory) I simply don't provide a link to the signup page unless someone is logged in. This opens the possibility that a knowledgeable hacker could craft a request manually, but the risk is very very low.
But I still like to do things the "right" way, so I am asking this question. I have looked at devise_invitable but that seems way too complex for my needs.
UPDATE: One experiment I tried was instead of instead of inheriting from Devise::RegistrationsController and overriding methods, I just copied it to my registrations_controller and edited it. Then I deleted the :require_no_authenticaton and :authenticate_scope! prepend_before_actions and replaced them with prepend_before_action :authenticate_user!
This should eliminate doubt about whether the before_actions were being processed in the wrong order and ensure that only :authenticate_user! was being called.
The experiment failed. Apparently :authenticate_user! always returns true at this point whether or not a user is really authenticated. Why?
Apparently this has been an issue with devise for a long time.
The workaround is to change the before_action to:
prepend_before_action -> {authenticate_user!(force:true)}, only: [:new, :create, :destroy]
as suggested in this issue comment.

devise: how to allow unauthenticated access to some pages?

I have implemented Rails with devise authentication. As part of the process I added a "global" before_action :authenticate_user! in the application_controller that requires that all pages must be authenticated.
# app/controllers/application_controllers.rb
class ApplicationController < ActionController::Base
before_action :authenticate_user!
end
How do I allow some controller#actions to be accessed without requiring the user to log in first.
This is useful when sending out mass emailings, and the email contains the link to a #show action which usually requires authentication.
Put skip_before_action :authenticate_user! inside your controller to allow all actions for that controller.
You can also use the only and except keywords in combination with it to only allow or forbid specific actions.
# skips authentication only for "index" and "show"
skip_before_action :authenticate_user! only: %i[index show]
# requires authentication only for "update" and "destroy"
skip_before_action :authenticate_user! except: %i[update destroy]
In the controller just mention the action that required log in:
before_action :authenticate_user!, :only => [:new, :create, :edit]
For example if you have the action 'send_mail' in the controller you can accessed without log in.

rails-4 autocomplete and devise authorization

I have a problem with the gem rails4-autocomplete. This works perfectly but since I have installed Devise for users I need to be connected to use autocompletion otherwise it does not work.
Indeed, if I withdraw the "Before_action: authenticate_user!" in the application_controller.rb, it works but I can not remove it.
How to skip authentication on rails4-autocomplete as on a method like to skip
authentication on index and show
Skip_before_action: authenticate_user !, only: [: index,: show]
How can I make it?
You might have figured this out by now, but the secret to your question is to run
rake routes
You'll notice that there is a named route created for your autocomplete. Then you'll just whitelist that method name (which you'll glean from the routing table)
So take a look at the routes, the one with "autocomplete" at the front of it is the one you need.
Then in the controller where your autocomplete is processed add a whitelist for devise if its on that action, like so:
skip_before_action :authenticate_user!, only [:index, :autocomplete_brand_website]
I threw together an example app that illustrates how this works in its most simplistic form:
https://bitbucket.org/bunglify/so-autocomplete-devise/overview
You can skip before_action on certain actions using except paramether:
before_action :authenticate_user!, except: [:index, :show]
also you can skip before_action that was inherited using skip_before_action in UsersController:
skip_before_action :authenticate_user!, only: [:index, :show]

Devise rubygem - How do you filter actions for authenticated/non-authenticated users?

I am new to Rails and I need to create a simple Rails project with these conditions:
there must be page with some articles (title + body)
anyone can read those articles
only authenticated users can create/edit/delete those articles
I used scaffold to generate a controller for articles and the gem Devise to create the authentication system. But I dont know how to implement the necessary conditions.
Thanks for the reply.
If your user model is called user, then you would include the following in your controller:
before_filter :authenticate_user!
If it not called user, you would replace the word user in authenticate_user with whatever it is.
You would add this directly under your controller declaration, like so:
class ArticlesController < ApplicationController
before_filter :authenticate_user!
#rest of code
end
If you want to restrict only certain actions in the controller to logged in users, you can use except to exclude some actions. Here, index and show can be seen by anyone:
before_filter :authenticate_user!, :except => [:index, :show]
or only to include specific actions. Here, only authenticated users can do the listed actions:
before_filter :authenticate_user!,
:only => [:new, :edit, :create, :update, :delete]

Devise::RegistrationsController#show

I have a controller which inherits from Devise::RegistrationsController. I have added a show action to the controller. The problem is that even when the user is logged out they can access this action even though at the top of my controller I have:
before_filter :authenticate_user!, :except => [:new, :create]
Why isn't authenticate_user! disallowing access to my show action?
I tested this with one of my application. The filter authentication_person! (it's person in my case) works well for all other controllers but doesn't work for controller inherited from Devise::RegistrationsController. This may be an issue or limitation with devise. Needs to be added to issues discussion at github.
The other workaround can be to create a filter method should_be_logged_in? into the application controller and then checking for person_signed_in? helper and redirecting accordingly.
Might be an issue with auth scope..
try adding the following to you controller:
prepend_before_filter :authenticate_scope!, :only => [:edit, :update, :destroy, :show]

Resources