dwyl / auth

πŸšͺ πŸ” UX-focussed Turnkey Authentication Solution for Web Apps/APIs (Documented, Tested & Maintained)
https://authdemo.fly.dev
GNU General Public License v2.0
131 stars 9 forks source link

How do we want to handle multiple applications using auth? #34

Closed RobStallion closed 4 years ago

RobStallion commented 5 years ago

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?

nelsonic commented 5 years ago

@RobStallion thanks for opening this question! πŸ•ΊπŸ» We need a diagram for this.

RobStallion commented 5 years ago

@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:

Pros

Using this approach people using our module will:

Cons

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.

nelsonic commented 5 years ago

@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. πŸ“

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.

RobStallion commented 5 years ago

My stack overflow question is here.

nelsonic commented 5 years ago

Auth Diagram: https://docs.google.com/presentation/d/1PUKzbRQOEgHaOmaEheU7T3AHQhRT8mhGuqVKotEJkM0 @RobStallion please LMK if you can access/edit it.

nelsonic commented 5 years ago

Diagram is public on the interwebs so anyone should be able to see and edit it: image

@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!)

RobStallion commented 5 years ago

@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.

Next step

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.

RobStallion commented 5 years ago

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.

nelsonic commented 5 years ago

@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?

RobStallion commented 5 years ago

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

nelsonic commented 4 years ago

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. guardian-uberauth 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: image

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:

  1. Decide where you're deploying your instance of auth. (e.g. localhost, Heroku or AWS) πŸ’‘
  2. Define the Environment Variables πŸ”‘ (it might take someone a few minutes to assemble all the API Keys they need e.g: Google API keys for Google Auth and AWS keys for sending emails)
  3. Deploy! πŸš€

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.

Next: https://github.com/dwyl/app/issues/268#issuecomment-583369990

nelsonic commented 4 years ago

GOTO: #42