Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Employee signin and signup #25

Open
6 tasks done
iamanujvrma opened this issue Apr 20, 2020 · 6 comments
Open
6 tasks done

Employee signin and signup #25

iamanujvrma opened this issue Apr 20, 2020 · 6 comments
Assignees
Labels
enhancement New feature or request go-backend

Comments

@iamanujvrma
Copy link
Contributor

iamanujvrma commented Apr 20, 2020

Tasks:

  • Add users table migration

  • Implement /login endpoint as per the flow

  • Add user_blacklisted_tokens table

  • Add logout API (this should create an entry of user token in user_blacklisted_tokens)

  • Task to clean up user_black_listed token when the token in table expires expires

  • Implement a way to check for valid login/JWT on each request (something we can call in http handler functions)

Acceptance criteria:

  1. New / Existing users should be able to login
  2. All users signed up from this flow should have Employee role
@iamanujvrma iamanujvrma added the enhancement New feature or request label Apr 20, 2020
@iamanujvrma iamanujvrma assigned jahio and mayuriardad and unassigned mayuriardad Apr 20, 2020
@jahio
Copy link
Contributor

jahio commented Apr 21, 2020

We're using BIGINT for our foreign keys in our users table here to accommodate larger integer sizes as the project database grows.

@iamanujvrma iamanujvrma changed the title [golang-backend] - Employee signin and signup Employee signin and signup Apr 23, 2020
@jahio
Copy link
Contributor

jahio commented Apr 29, 2020

I wanted to bring up a few things here about the flow as it's spelled out, simply because I think it may be trying to get us to do too much that's already handled by Google's oauth system.

  1. Client will collect google-auth-token received from google signin.
  2. Client will initiate POST request for login to Node API with google-auth-token in request body.
  3. API should authenticate this google-auth-token with google services and fetch user profile.

This sounds like it's more trouble than it's worth. Can we simply follow the regular oauth2 callback flow (GET /auth/google, redirect to google login, login, then GET /auth/google/callback)? Because that final step will allow us to generate and issue a valid JWT to pass to the client, and since it'll be encrypted using a known/private secret, and sent with every request, we won't have to check with Google again - if we can read it and it's valid, we gave it out so we know they're authenticated.

  1. Fetch email from user profile and check if user with this email id exists in users table.
  2. If user is present in database and is not soft deleted, generate jwt token and send in the response along with user role.

Why do we need to check if the user already exists? If Google authenticated them for our organization, we know they're valid and that they're part of Josh Software. You can control that organizational authentication measure via the google developer console.

Screen Shot 2020-04-29 at 5 43 54 PM

It's OK to check for soft deletion and fail authentication/refuse to issue a JWT if they've been soft deleted, but the other issues remain.

  1. If user is not present in database, then fetch domain of user email from user profile.
  2. Check if organisation with that domain exists in database.

Shouldn't be necessary since we're limiting auth to the organization in Google's settings.

  1. If organisation exists with that domain, add that user in users table and generate and send jwt token in response along with user role. (For new user signing up back end should add "Employee" as user role. Note: We need to finalise how can we add user as moderator.)

Minus the organization/domain part, this makes sense. If Google authenticates them under our organization, we can automatically assume they're allowed to use the system (soft-deletion withstanding).

  1. If user domain is not matching with any organisation, simple return 401.

Again, we don't need to do this because it'll fail authentication on Google's end if we follow the normal redirect-based oauth flow.

The flow document seems to want us to build the logic of testing to see if the user is part of our organization, but Google's oauth settings for something like this allow Google to do that for you. So in other words, what I have working right now will authenticate anyone with a joshsoftware.com account, but no one else (even with another google account). I tested this locally and it does appear to work fine.

Screen Shot 2020-04-29 at 5 37 12 PM

What I have working right now makes use of https://github.com/markbates/goth to handle oauth2 authentication via Google accounts, and it works fine. As of today, we could start issuing JWTs right here in the code. But that's only if we can follow the normal flow that's set up here.

Basically what I'm trying to do here is see if we can make some adjustments to this process so we can make use of a library instead of having to dig into the internals of oauth2 in order to implement this ourselves.

@the-spectator
Copy link
Contributor

@sahilbhatia
Copy link
Contributor

sahilbhatia commented May 2, 2020

@jahio - We had an internal discussion between @anilmaurya, @iamanujvrma, @sunil4sonawane and I. Summarizing our discussion below:

We need to support the following:

  • Loose coupling between UI and API (i.e. server cannot render the view)
  • Multi tenancy
  • Allow sign-in only using organization's domain
  • Multiple SSO providers

Considering these, we felt the current approach is pretty straightforwad and meets our requirements.

  • In the current approach, UI show a google sign-in page in a pop-up window and get's a JWT token in response.
  • This token is sent to API via "Authorization" header
  • Server can choose to either:
  • Decoded token contains "hd" key specifying user's "domain"
  • Backend finds the org matching domain and finds or create user against that org
  • Finally, Backend return JWT token associated with that user to UI
  • UI uses this JWT token for all subsequent API calls

We were unable to understand the complications you are facing and are happy to dicuss those OR what made you feel it's not the standard OAuth flow?

The difference I see in our approach is that GET /auth/google/callback is received by client (in our approach) rather than server (as you suggested). BTW, you didn't mention how will server pass on the token to client in your approach.


To answer your questions:

  1. Because that final step will allow us to generate and issue a valid JWT to pass to the client, and since it'll be encrypted using a known/private secret - JWT token is not encrypted. It can be read by everyone. However, to modify the contents, you need "secret key".

  2. Why do we need to check if the user already exists? If Google authenticated them for our organization, we know they're valid and that they're part of Josh Software - we are verifying two things here: (1) An organization exists in our DB (or is registered with us) for the domain used for sign-in. (2) User of that organization also exists in our DB.

We are making these checks as we issue JWT token against users in our DB. i.e. we are not support JWT token provided by Google for internal API calls.

@jahio
Copy link
Contributor

jahio commented May 9, 2020

Just a status update here: Sahil and I discussed this earlier in the week and he helped me get some clarity around what's what. I've got the login-flow branch I've been working on, and I've finally as of today got it properly authenticating with Google "under the hood" (via API). I'm still working on the logic to check if the authenticated user is a member of a known organization and issuing the JWT itself, so that's what I plan to work on next week assuming I'm not assigned to a higher priority task.

@jahio
Copy link
Contributor

jahio commented May 15, 2020

iamanujvrma added a commit that referenced this issue Jun 2, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request go-backend
Projects
None yet
Development

No branches or pull requests

5 participants