Authenticating different types of users

So I started getting used to phx.gen.auth and I quite like it at this point. Now I wanted to get some suggestions about something. I’m working on a solution with a “back office” in which users set up real estates (basically gated communities) and assign users to those estates. The other part of the application sees the staff of the real estate being able to log in and perform tasks.

So back office users are not attached to a real estate. Front end users are. I can currently think of 3 ways I cold organize this.

  1. I run phx.get.auth twice to create to distinct types of users that have access to entirely different parts of the site. To me, this seems logical and easy to set up, but I’m probably not aware of some or other gotcha
  2. I keep a single user model and create a second table to associate users with housing estates. This also makes a lot of sense and wouldn’t be much more difficult to set up. Again, I’m not entire sure about the eventual downsides, so hope to get some feedback
  3. I develop the back office as a completely separate app, thereby reducing the need to even think about this issue. Communication between the two apps is done either via (3a) sharing the database or (3b) setting up API endpoints on each side.

I’ll be honest, I am strongly biased against 3, since I love monoliths and moreover (3b) in particular seems like a lot of extra work. However, I’m trying to be open-minded and hear pros and cons of each solution, or even a completely different one proposed. My mind leans towards 1 being the “best” option but I’m used to ending up with a mess because I take a quick decision without properly thinking of the consequences, hence this post.

The relational model basically exists to support option 2.

The “gotcha” with option 1 is that you’re duplicating massive swathes of functionality (auth) that should be shared. You don’t perceive the pain associated with this because you have a magic button (mix phx.gen.auth) that writes the code for you. Once you actually have to maintain that code, you will suffer proportionately.

Option 3 is fine if they’re really separate apps but the fact that you even felt the need to make this post is a pretty good indicator that they are not.

Thinking things through is great and all, but the only way to get better is to practice. If you want to learn how not to make a mess, write more code and force yourself to maintain it. You will eventually learn what works and what doesn’t, and we call that “experience” :slight_smile:

4 Likes

That would seem to make a lot of sense.

Oh, I have no problems practicing. I’m just a bit impulsive and always have been. My first attempts at writing games on the C64 usually ended up with me creating a royal mess and spending God knows how many hours trying to unwind it. But it was a lot of fun.

2 Likes

Did you look at the documentation with mix help phx.gen.auth? I remember reading about exactly the first scenario in there, where you generate twice the authentication for different users.

Personally I tend to keep authentication a completely separate concern to authorization and business logic. It’s a technical setup necessary to try to identify a user who can act on the system. That part of a system is likely quite stable. What’s less stable is what a user is allowed to do within a system. What if down the line there comes a request for estates managed by local personnel. Suddenly (some of) your frontend users are at the same time a back office user scoped to a single estate. That doesn’t and shouldn’t really affect the technical parts of login and user authentication, but it very much affects authorization. Neither option 3 nor 1 would be particularly well suited for such a change.

3 Likes

Yes, I did. I wasn’t really looking for how to set it up but more opinions on which solution people think is the “best” and hopefully a bit of a justification.

It’s curious, we were just discussing that eventuality the other day. Seems like the team is of the opinion that in such a case that user would have to user two separate accounts. I’m still left to be convinced.

So stable, in fact, that many try to factor it out of the application entirely (with OAuth/OpenID/etc).

Imo that‘s making bad software design the users problem. It sometimes makes sense if e.g. its the same users business vs private identity, but it for sure shouldn‘t be the case if both roles in relation to the software project are part of one job in real life. Making it a requirement might even mean someone needs an additional email, not using their employment assigned email, more passwords and generally stuff you actually do not want.

In the end at runtime I‘d argue it shouldn‘t matter if you make decisions based on user a vs b or user a in role a vs b, while the latter is more flexible.

1 Like