Best practices on securing admin area


I’m building a small Phoenix project where my goal is to build whole bunch of different features that are applicable in the real world and learn both Elixir and Phoenix this way. So, I’ve started building admin area where I can see all the users, block, delete them etc. Right now, there is a single login that is used by both admin and regular users and if a user is an admin, they get redirected to /admin path.

Can you please share some advice or best practices on how to secure and protect this admin area or maybe hide it to avoid possible security attacks as much as possible?

So what you are looking for is Authorization.

In web development we have two concepts around users and permissions, Authentication & Authorization.

Authentication is how we identify who someone is, that is usually done by a username and a password or by a token. Then Authorization are permissions of what this user is allowed to do.

For Authorization there can be many techniques or libraries. For example you could keep two user tables, the regular user and admins, then the Admin table is allowed everywhere while the User table can only see “normal” content. Another way is to have a single Users table, but include a permissions row, it can be a list for example with the different “roles”, then in the admin dashboard you make sure they have access to the “Admin” role.

There can be other techniques, you could even add a http_basic auth for that route, or have it accessible only through certain restrictions (as IP tunneling, etc, however that might be overcomplicated for this situation).

Hope this helps :slight_smile:

1 Like

In router.ex, you can have

  scope "/admin", Admin do
    pipe_through [:browser, :require_admin]
    ... // routes

You have to import module which contains function require_admin(conn, opts \\ []) in which you can validate if the user is admin or not. For which I suggest second advice from above post, to have an admin role. So then you could have in with pipe a validation function which returns :ok or error tuple:
:ok <- validate(user.role in [:admin, :super_admin], "User not admin")

1 Like