dimitarvp

dimitarvp

Hey everybody! :039:
I am looking for the auth framework that can help me with a project, given these specifics:

  1. There are no public sections or pages. Non-authenticated users can only land on the home page and they cannot go anywhere else before signing in.
  2. You cannot just sign up. An admin has to invite you first and you get a link in your email inbox that allows you to then sign up. The classic sign up model is either out of the question, or as a compromise it can be implemented only if the new account has to be approved by an admin before being able to sign in.
  3. As per above: there should be admins and users and admins can approve user accounts.
  4. The framework should allow for more roles than admin and user in the future – but I am guessing I have to study how can an authorization library work with the chosen framework or homegrown solution instead.
  5. The framework should in general be extensible in a non-bloated way, meaning if I want to customize something it does I shouldn’t have to copy several files 200+ lines long and then apply 3-line diffs to them. I know this is a very tough thing to do, it’s just that I would gladly take it if it was out there.

I looked at both Coherence and Pow. Also entertained the idea of Guardian with my own code on top.


Notes about Coherence:

  • Coherence seems to carry a lot of file baggage with it and integrates very tightly with myapp_web which I don’t like and I don’t have the time to untangle properly into a separate auth app inside an umbrella. I definitely could do it in theory but I have no guarantee that it’s only an 1-2 hour job which is scaring me and thus I haven’t tried that yet.
  • I suffered a problem with it caching the user model so aggressively that a linked belongs_to object was never really invalidated and reloaded and was thus showing wrong data on the pages. I was forced to instruct Coherence to copy its controllers inside the project and to then overwrite how they load the user model. Result: no caching at all, every page incurs a reload of the user itself and its linked object. Basically defeated the really neat idea that the Coherence author had. :frowning: This is definitely my bad and not of Coherence! But in the 10 minutes I tried to find a solution, I failed.
  • It does indeed support invitations but I admit I haven’t tried to disable normal sign up and gate it behind an invitation only. So I am not sure if my desired use-case is supported out of the box, if it’s possible with a small effort, or would be a hassle to achieve (but still possible).

/CC @smpallen99, the author of Coherence.


Notes about Pow:

  • A bit smaller than Coherence but basically has the same problem of file baggage and no umbrella-friendly installer (namely no option to generate an entirely separate app inside an umbrella). I really don’t know why library/framework authors don’t make this a first-class citizen in their mix tasks, it would be very highly appreciated!
  • Didn’t seem to capture my use case about being able to invite users and not allow them to sign in before approved by an admin. I liked the author’s response when I asked him – what he proposed sounded easy enough – it’s just that in a startup scenario you really cannot get distracted with customizing frameworks when you are building an MVP. You either have to use ready-baked solutions or know exactly what you are doing when customizing (and thus still do it very quickly). Every hour counts in these conditions.

/CC @danschultzer, the author of Pow.


Admittedly I am not an expert in both of these and sadly the time is really not right for me to indulge in weeks-long toy projects to inform myself properly.

Finally, I looked into Guardian because I used it before. It’s really easy and minimastlic to start with and is currently the decision I lean to (in combination with comeonin and my own DB model for invitations). Not really sure if it wouldn’t quickly get harder than Coherence and Pow though.

Don’t get me wrong. I am not lazy. I am open to devote to one framework and then become an expert – subsequently it’s likely I would be contributing to it as well. But right now I am really pressed with time and I am looking for a practical advice before pulling the trigger.

Any advice and battle stories are appreciated. Thanks for your consideration! :023:

Showing Posts 1 to 10

danschultzer

danschultzer

Pow Core Team

Just a sidenote: Pow installer can be used easily in umbrella setups. You have to run mix pow.ecto.install -r MyApp.Repo in your ecto app and mix pow.phoenix.install -r MyApp.Repo in your phoenix app.

It’s impossible to know what kind of umbrella setup a project is, so this can’t be done automatically. However I think it would be useful to show a notice about how to do this when running pow.install in the umbrella app root.

I almost exclusively work with umbrella apps myself :smile:

dimitarvp

dimitarvp OP

Great tidbits! I will try those. :slight_smile:

As for an installer, I would think something like mix pow.install --umbrella --new_app pow_auth could be enough? I don’t mean that your installer has to parse the structure of the umbrella app, no – I mean that with some more CLI options as you showed above, the Pow installer can just create an entirely separate app inside the umbrella that’s exclusively used for authentication with Pow?

Sorry if I am misunderstanding.

EDIT: I keep forgetting that eventually you do have to edit your web app’s router.ex file though.

danschultzer

danschultzer

Pow Core Team

Unfortunately that would require that Pow also creates a Phoenix app which is outside the scope of the Pow mix tasks. Most of the time you would want to have you sign in and registration views the same place as your default Phoenix app.

dimitarvp

dimitarvp OP

I understand. But as an unfortunate side effect any auth library one picks up becomes a strongly entrenched dependency inside your web app’s files which you cannot easily replace if something else is serving you better down the line.

danschultzer

danschultzer

Pow Core Team

True. It’s been something I’ve experienced with other authentication libraries for Elixir/Phoenix, so I’ve tried to make a very transparent API for Pow that makes it easier to replace if something fits better down the line. The goal has been to have as few files as possible generated or modified, and make any developer understand how Pow works by taking it step by step to e.g. enable extensions, or modify templates.

With umbrella apps it’s possible to limit this, but you’ll have to work with multiple Phoenix apps, endpoints, cross check sessions, etc, and at that point a detached authentication server may make more sense.

MrDoops

MrDoops

Outside of Pow and Guardian, the other authentication library/framework I’ve liked in this space is Phauxth. There’s been some recent updates, and the code is easy to read and well documented, so at least worth reading through if you’re planning on spinning your own authentication solution.

I’ve got a greenfield application scoped out that will need similar admin-invite capabilities, so I’m interested to see what solution you work out.

nsweeting

nsweeting

If you’re willing to accept a token-based approach, I created Authex. It has support for authentication + authorization, is pretty minimal in its approach, and is umbrella friendly. It may work depending on your needs.

https://github.com/nsweeting/authex

smpallen99

smpallen99

I’m really interested in what you don’t like? Are you not using the standard web structure?

Yes that is the downside of caching the user data. I’ve never come across the issue of a stale belongs_to, but completely understand the issue. The choices are either fetch the preloaded user schema on each request, or calling the API to update the cache.

BTW, if you want to fetch the user on each request, you could to that with a plug pretty easy. No changes to Coherence.

# lib/my_app_web/router.ex
def reload_user_data(%{assigns: %{current_user: %{id: id}}} = conn, _) do
    user = MyApp.Repo.get(id, preload: [...])
    assign(conn, :current_user, user)
end

def reload_user_data(conn, _) do
  conn
end

and then put that plug after the coherence plugs in each of your pipelines

Yes it is. Just don’t install the registerable option. This way, new accounts are either created somewhere in your app, or by sending them an invitation.

BTW, I have just overhauled custom controllers. The generated controllers are now < 10 lines long, with all the supporting actions and helpers overridable.

Thanks for sharing your experience with Coherence.

dimitarvp

dimitarvp OP

Apologies to everyone for the silence, I will respond properly when I get some free time somewhere in the next 24h.

jordiee

jordiee

https://github.com/AppDoctorIo/accesspass

My library should be able to cover all your use cases as it offers a vast amount of customization via a behavior. There are still some github issues I want to get to in the future that would make it an even better fit but it absolutely can do everything your looking for now in a fairly easy way. I should note that it is for api authentication and would still need a ui built around it. I made it for my project https://appdoctor.io . I currently only allow new accounts with a provided beta code. You can do much the same thing via your email strategy mentioned.

Here is a post I did a while back going into more detail on why I made it:

https://medium.com/appdoctor/accesspass-yet-another-elixir-authentication-library-7ea59734a49

and any pull requests/contribution is VERY welcome!

A big plus at least for me is ease of use in a new project. It provides a drop in plug and macro to handle everything in 3 lines of code for auth.

Also mind you this solution was originally not made to be open sourced so a lot of the current github issues deal with braking away from what I had as original defaults.

Where Next? Top

Trending in Questions Top

RSP87
I’m working on a project that simulates the bumbl example in the programming phoenix book. It acts almost like an email client. We have a...
New
nseaSeb
Hello, I know there is an approach for handling lists that allows for optimized traversal, but I can’t recall the specific method (somet...
New
brecabral
Documentation While reading the Scoped Routes section, I noticed that the documentation currently refers to a problem without explainin...
New
RemyXRenard
I’m seeing that a list inside a Kino.DataTable will be interpreted as a charlist, even if the Kino.configure() is set to charlists: :as_l...
New
velrest
So my question is quite simple and i have found no conclusive answer on forum, google or AI. Should we use :erlang.float for Integer to ...
New
samoloth
Hi, I’ve just set up an application with ash_authentication. There is only magic link strategy for now, so there is no confirmation add o...
New
asweet-confluent
I recently noticed that Elixir’s Logger defaults its primary log level to :debug when no :logger, :level application configuration is pre...
New

Other Trending Topics Top

JesseHerrick
Hey, I’m Jesse and I’m the main contributor behind Dexter, a full-featured, lightning-fast Elixir LSP optimized for large codebases. It s...
New
mudasobwa
I am happy to introduce the very α version of the new programming language compiled to BEAM. Welcome Cure. It has literally three kille...
New
marciok
Hi there! We created Gust: A task orchestrator inspired by Airflow. For those who have never heard about Aiflow, it’s a Python-based wor...
New
mhanberg
Hi everyone! The first release candidate for the Expert language server project is now available! We’ve published a press release detai...
New
jimsynz
Beam Bots (or just BB for short) is a framework for building fault-tolerant robotics applications in Elixir using familiar OTP patterns. ...
New
Dmk
Xamal is a deployment tool for Elixir apps that deploys native releases to bare metal servers over SSH. It’s a port of GitHub - basecamp/...
New

Latest on Elixir Forum

Elixir Forum

We're in Beta

About us Mission Statement

Options

Thread Display Mode




Thread Preview

Skip Thread Previews