DanielNordby
DanielNordby

Reputation: 579

Secure Admin registration with Devise

I feel like the answer is "it's build in, dummy" but I can't find the documentation to verify my suspicions.

I'm using Devise for a Rails app and my question, in short, is: "how do I create new admin users?" The reason I ask is that following the Devise documentation seems to just create a structure that would expose the /admins/sign_up URL, similar to how it exposes the /users/sign_up URL for new users.

Now, generally, I wouldn't expect anyone to go to /admins/sign_up just to see if they could. But I don't really want to bank on that, and create a (pretty gaping) vulnerability. So, my follow up question is: "how do I secure the admin signup so that only the right people see it?" and/or "what is a better alternative to handle admin accounts with devise?"

EDIT 1
I found discovered (in their docs) the obvious answer to securing the admin sign up. If I remove :registerable and a couple other configuration options in the admin model, and run the migration with the appropriate settings, the route simply isn't available to reach any kind of admin signup. Great.

I guess my first question now still stands: "how do I now create a new admin?" It's not like just anyone can go in and register to be an admin now, but I also don't see how I or anyone else could create an admin account.

Upvotes: 0

Views: 752

Answers (1)

Qaisar Nadeem
Qaisar Nadeem

Reputation: 2434

Devise is great gem for authentication but It lacks some of the key features like you wanted only admin to create users. It's pretty much general purpose requirement for lot of projects.

There is not a single line solution in devise for this problem.

Here are few things which devise does/suppose.

  1. Signup is public
  2. Already login user cannot sign up
  3. Newly signed up user is auto logged in after successful signup.

Now we are going to change all of the above three behaviour

I am assuming your model for users is user and configuring devise for user

First of all you need to override devise registration controller.

 ## app/controllers/registrations_controller.rb
class RegistrationsController < Devise::RegistrationsController
  before_action :authenticate_user!, :redirect_unless_admin,  only: [:new, :create]
  skip_before_action :require_no_authentication

  private
  def redirect_unless_admin
    unless current_user.try(:admin?)
      flash[:error] = "Only admins can do that"
      redirect_to root_path
    end
  end

  def sign_up(resource_name, resource)
    true
  end
end


# config/routes.rb
Rails.application.routes.draw do
  devise_for :users, :controllers => { :registrations => 'registrations'}
end

Here is how all of the above three issues are handled.

  1. The before_action ensures that a user is logged in, and redirects them unless they are admin, if they try to sign up.
  2. The already logged in issue is caused by Devise's require_no_authentication method and skipping it resolves the issue.
  3. Next is that the newly created user is automatically signed in. The sign_up helper method which does this is overridden to do prevent automatic signin.

Upvotes: 2

Related Questions