Closed RobStallion closed 4 years ago
@RobStallion thanks for opening this question! πΊπ» We need a diagram for this.
@nelsonic After reading programming-phx 1.4 my thoughts on how the auth app might work have changed some and I wanted to run my current thoughts passed you.
They talk about separating a users sensitive and non-sensitive information into different places in the application and database. All the non-sensitive info (username, name, etc) is put in the users table while the sensitive info (email, password, etc) is put in the credentials table.
Auth will:
this is thinking of the auth app in the most basic way at the moment and not including the other tables that it will need to contain (e.g. sessions table).
Using this approach people using our module will:
Using this approach people using our module will
Please let me know your thoughts on any of this. This is my no means a finished idea. I also have a SO question open relating to how we would best implement something along these lines here.
@RobStallion technically all user data is sensitive (according to GDPR)
Yes, in the context of GitHub a username
is public
but imagine we are building something for the NHS which would have a "forum" where vulnerable people could interact with and seek help from medical professionals. The person's chosen username
and especially their name
are highly personal and need to be encrypted and stored appropriately.
The Programming Phoenix Book (v1.4) is good for the technical implementation especially contexts, but it's not written from a maximum privacy perspective (and is certainly not GDPR-compliant) please treat the book as a "guide" not a "gospel" when building Auth.
For our purposes all people-related data is sensitive. There is no advantage to splitting out "credentials" into its' own table as we will always select and decrypt the Name of the person (in order to display it in the UI) on a successful login. This is why a login flow diagram is necessary. π
Rob, if you have time today we should pair on a Diagram to clarify this for ourselves and others. π
auth
is the best thing for privacy.
Note: we may re-visit this later if we want to give people the
<option>
of using the same DB as their main Phoenix App, but for now it should be completely separate.
Auth.session_verify
function which should be it's own Hex module that should be included into any app and used to verify a session validity.
GET /auth/personal_details
We must figure out how to integrate this with Phoenix Sessions: phoenixframework.org/blog/sessions
Please share the link to the StackOverflow question you opened on this when you can.
My stack overflow question is here.
Auth Diagram: https://docs.google.com/presentation/d/1PUKzbRQOEgHaOmaEheU7T3AHQhRT8mhGuqVKotEJkM0 @RobStallion please LMK if you can access/edit it.
Diagram is public on the interwebs so anyone should be able to see and edit it:
@RobStallion if you have time to walk through the requirement for sending an email with a link to "verify email address" with @Cleop please go for it. the issue is: https://github.com/dwyl/auth/issues/35 (thanks!)
@nelsonic I have created 2 basic phoenix applications called regular_app
and auth_app
.
regular_app
is pretty much just a default phx.new
project. I have added httpoison
to the deps and and using it to make requests.
auth_app
is the app you make following the programming-phx-1.4 book (up till chapter 5 as that is where they cover auth). It has basic login/logout functionality.
So far I have been able to get regular_app
to send a post
request to auth_app
with json of a username and password. That user can then be verified in auth_app
and a json response can be sent back to regular_app
.
I know that this ins't exactly what we talked about when we made the login diagram but I figured we would need to be able to do something similar to this for a newsletter registration type event anyway so it would be good knowledge to have.
Have regular_app
link to auth_app
's login page. Once login has been completed in auth_app
send the user back to the page they came from in regular_app
(look into http referer as a poss way).
Once I am back in regular_app
, make a GET request to auth_app
to check the session is valid. My first guess is that regular_app
will need an "auth_plug" type of thing that will handle making this request for all incoming requests but we'll see.
I have updated my test apps.
regular_app
has a link on the landing page that links to auth_app
Once in auth_app
I get the http_referer
like so...
referer = get_req_header(conn, "referer")
render(conn, "new.html", referer: referer)
and send it to the login form which has it as a hidden field.
I log in as normal in the auth_app
. If log in is successful however it redirects back to regular_app
like so...
redirect(conn, external: referer)
auth_app
creates puts the user_id
in the session
on login like so...
def login(conn, user) do
conn
|> assign(:current_user, user)
|> put_session(:user_id, user.id)
|> configure_session(renew: true)
end
Not sure on best way of sending this info back to regular_app
at the moment.
@RobStallion worth opening a separate issue e.g. in learn-elixir
and describing the problem as a "SSCCE" so that you can ask it on SO/Elixir Forum and capture the answer?
Have been doing a fair amount of reading up on session vs token based auth...
And the impact that this could have on the way we want to build auth.
The Phoenix book shows us how do auth with session auth, as seen in this comment above
Guardian is a token based authentication library for use with Elixir applications and can be used to create JWTs.
@nelsonic You mentioned that you did not want to use Guardian in this comment but said it was a closer approximation to what we need.
I looked into how it is used in elixir apps (I have never used it personally so needed to look at some examples. The first link above is a good example) and they have made the implementation of it fairly similar to the examples from the book, e.g. they create an auth plug and pipe incoming requests that need to be verified through said plug.
My current understanding of how JWTs are verified is through the "secret" in them. JWTs are made up of header.payload.secret
. This secret or signature is what the receiving app uses to verify the request.
I think that we would be able to create an api this way fairly easily. E.g. a user would login by sending a post request to auth_app
, auth_app
would do the logic and send back json (a JWT).
However, if we want to redirect users to auth_app
and then redirect back to regular_app
as mentioned, we will need to pass the JWT back in the redirect. I am not sure how we will do this ATM but I think we should be able to do it will Plug.Conn.put_resp_header/3.
Once back in regular_app
we will need to be able to verify the JWT when needed. I assume that if regular app has the access to the same secret/signature
used in auth_app
we will be able to verify the JWT without having to make further requests to auth_app
(unless we need a users data of course, in which case we could have a simple api set up for this)
@nelsonic Let me know your thoughts
The idea of using ueberauth/guardian is a non-starter for me. π
If you read through the docs for Guardian there is a lot of text but not a single diagram. π€·ββ
See: https://github.com/ueberauth/guardian/blob/guides/introduction/overview.md π
How does someone explain a complex topic like Auth without any diagrams? π€¦ββ
Something as simple as this: https://github.com/dwyl/hapi-auth-jwt2#understanding-the-request-flow would be a lot better than large blocks of text and nothing visual.
This is not a "niggle", it's a symptom of a bigger problem: complexity.
The first line of the docs informs me that I'm going to have to create an "implementation module".
Why? Why isn't there a default
one already included that I can use immediately.
It reminds me of:
We can simplify our Auth by an order of magnitude by just building exactly what we need from scratch. We want our "setup" instructions to be:
auth
. (e.g. localhost
, Heroku or AWS) π‘ That's it. No more configuration or steps required. Get back to building the features of the app
.
Obviously, to achieve this level of "batteries included" simplicity, we have to do a lot of work on our end.
GOTO: #42
My current understanding of how
auth
will work is that it will be a separate application that a calling app forwards requests to.If this is correct, how do we want to handle multiple applications using auth? Would we deploy multiple versions of the auth app? Would one auth application handle multiple calling apps?