Closed Danwhy closed 4 years ago
@Danwhy firstly thank you for proactively opening this issue to ask this question and capture the resulting research, discussion and answer. 🥇
As described in the diagram and accompanying text in https://github.com/dwyl/technology-stack/issues/67 auth
needs to be a "general purpose" authentication solution that we can "drop-in" to any App.
I expect it to take us decent chunk of effort to get it to the point where I will feel "happy".
Yes, the plan is to namespace all controllers under /auth
such that any app that uses the auth
package forwards requests to the /auth
endpoints.
I do not foresee a situation where the "main" application would invoke an auth
function. 💭
Instead, I expect us to have an auth_config.exs
file (name TBD) where all options
are clearly listed declaratively in order to override our (carefully considered) default
values.
If you are heading in the Umbrella App direction, then you are on the "right track". ✅ (at least to my knowledge of Phoenix, this is still the way it's done in Programming Phoenix 1.4 [book])
We need a separate issue for how we are going to require the auth_config.exs
file.
(as always, feel free to take the lead on opening it and assign if you have questions...)
_To be clear we aren't going to use
Überauth
because my recent reading of the source code indicated that it only provides a superficial functionality and then requires us (the "integrators") to provide the rest.Guardian
is a closer approximation of what we need but it's still miles off the end result. We can use these two packages as "inspiration" and even "borrow" chunks of code (with the appropriate attribution), but we are not going to use either as a dependency because they are not "fit for purpose"; not even close. So please ignore any code that usesÜberauth
as it will beDELETED
in due course_.
I am very grateful that you made the effort to update the PR: https://github.com/dwyl/auth/pull/9 to Phoenix 1.4
but we need to "take a step back" and focus on the dependencies of auth
as described in #67
Specifically the "foundational" module alog
is only about 10% complete
and it needs to be at around 80% before
we can begin work on auth
.
The current master
is only 5% documented which has lead members
of @dwyl's core team to be "confused" as to how it works ...
we cannot afford for the documentation of any of our code to be less than "wow".
To be clear: this is not a "criticism" of your work, Dan, you have done a "good job" so far on getting
alog
to "Alpha" state so that it could be used in the client project. Thank you! 👍 Just that we need to keep going on building the foundationbefore
we build the fortress. 🏰
@SimonLab has made a start with documenting alog
: https://github.com/dwyl/alog/pull/20
(and that PR must be finished ASAP)
But we will need to re-work some of the "internals" of alog
to use a cid
("Content ID") instead of an entry_id
so that our records are identified by the hash of the content rather than by a random UUID
.
I opened the issue to discuss this: https://github.com/dwyl/alog/issues/15 but I did not impose my preference at the time because I did not want to distract you or the team working on the client project as it would have delayed the shipping of the client project to work on cid
.
Now that the client project has shipped (🎉) and we have a little time to breath, ☁️
we need to put in the time to re-work how alog
operates to ensure
that we create the appropriate foundation for our apps.
With that in mind, I need your help with the following issue: https://github.com/dwyl/cid/issues/11
We need to implement a cid
function that produces a consistent/deterministic hash of any content so that when we append a record to our append-only-log, we can easily see when data changes (or when the record was submitted with identical data and thus no DB insertion is required).
Once the cid
is working, we can use it in alog
which in turn will be used by auth
.
All login attempts and success need to be logged in an append-only (auditable) log.
Therefore we must get the underlying layer right before
we proceed.
Sessions will be stored in alog
and all metrics / events will be alog
such as "verification email sent", "account verified", "password reset email sent", etc.
Your benchmark as a "senior" developer must be that: members of the wider community (beyond @dwyl team) are using the code you write. If you achieve code re-use beyond your own immediate needs, you have levelled up to "senior". Right now
alog
is not in a "useable" state for anyone beyond "us" (@dwyl). The functionality and docs need to get to the point where people in the wider Elixir community can use them. When we see the first issue being opened by someone who is not already a member of @dwyl then we know that we have achieved reuse-ability / usefulness.
Please continue to open/ask questions like this one.
Re-read the Programming Phoenix 1.4 Book and see how Auth is done in the book.
Then apply that knowledge to an append-only log using alog
(with cid
as ids).
The resulting auth
package should be an Umbrella App that any other Phoenix App can use.
@nelsonic What we've got so far is a working implementation of auth in an example app, but how should we go about using it in other projects?
Is the intention to keep the code in the form it is now when requiring it into other apps? By this I mean the logic being performed in the
controllers
so that all the parent application has to do is forward all requests to/auth
endpoints to this application, rather than the alternative which, would just be exposing the functions in this app and the parent module calling these functions to perform authorisation.You mentioned in https://github.com/dwyl/technology-stack/issues/67#issuecomment-437145610 that Auth should eventually be its own, separately hosted umbrella app, so to me this does seem like a step towards that.
I have managed to get this method of integrating the apps working, but just wanted to check I wasn't heading in the wrong direction.
The main issue I had in getting this approach to work was the configuration. Dependency config files are not included when they are required as a dependency, as it is expected that the calling module will provide the config. This was a problem as the Ueberauth plug that is being used in the
auth_controller
expects some configuration to be set before it is compiled, so an error was being thrown. My solution to overcome this was to useApplication.put_env
to set the config before the plug is called. This way we can set the config we want to specify inAuth
, and also read from the parent app's config file (withApplication.get_env
), allowing certain configurations to be set.