1

I am trying to add OAuth to my application using react-native(expo), node.js, and mongodb. Currently I am just working on implementing google authentication with the "google-auth-library" package on the backend. I am able to get all of the data that I need (access-token, id-token, email, username, etc.), but I'm not sure how to store that in the database. Along with the google authentication, I also have my own authentication using an email/password combination. The first question I have is, since mongodb automatically generates the objectID for each document, would I have to add a "googleID" field to the User model in order to differentiate the users that sign in using google? It doesn't seem like an optimal solution since if tomorrow if I want to add facebook authentication, I'll have to then add a "facebookID" field and then repeat this for any authentication I want to add. Is there a better way to differentiate users that use different authentication methods? And my other question is, since I have my own authentication, how do I treat the "password" field for users that sign in with google? Since I don't have their password in my database, would I conditionally check their password only if they are signing in with my personal authentication system? And similarly, would I only require a password to be provided from users not using google when they register an account? Hopefully those questions make sense and thank you to anyone who can help.

Max
  • 285
  • 3
  • 15

1 Answers1

2

The first question I have is, since mongodb automatically generates the objectID for each document, would I have to add a "googleID" field to the User model in order to differentiate the users that sign in using google?

You would want to setup a second collection for tokens, and either embed them in the user Or you would want to store the tokens in their own collection and store the user id on the token with the googleID as a field on the record. You can store the token with a "tokenType" and then a "value" for the tokens OAUTH provided id.

as for how to write the embed with react-native You may want to look at documentation for the library mongoose for nodejs for additional understanding. Mongodb is a NoSQL database that lives and breathes embedded records.

And my other question is, since I have my own authentication, how do I treat the "password" field for users that sign in with google? Since I don't have their password in my database, would I conditionally check their password only if they are signing in with my personal authentication system? And similarly, would I only require a password to be provided from users not using google when they register an account?

with OAUTH you have to store the token in the device, and refresh it with the refresh token that the OAUTH provider gives you. When they provide the token, you lookup that token on your database and identify what user/email that token belongs to. And attempt to refresh it if its expired.

alilland
  • 2,039
  • 1
  • 21
  • 42
  • 1
    So for a token collection, are you saying to store something like this: ` { tokenType: "google", value: "some-google-id", userID: "objectID-generated-by-mongo" }` and then whenever I verify the user's googleID upon signing in, I then get the user's data based on the "userID" associated with the googlID? – Max Jul 10 '21 at 04:26
  • 1
    yep, thats one way – alilland Jul 10 '21 at 04:27
  • 1
    And then for storing the token on the device, should I store both the access-token (as google calls it) and the refresh-token? Or just the access-token and then I receive a new refresh token each time the user attempts to sign in? Sorry, this part is a little less clear to me. – Max Jul 10 '21 at 04:36
  • 1
    you will store the access token on the device (if a web browser you could store it as a cookie or on local storage), then you will check to see if you have the token in your database. If you do - check it if it has expired, or you can check if it has expired first (they are usually JWT tokens that you can decrypt). If it has expired, you use the refresh token that you saved on the backend (never expose the refresh token publicly). The refresh token is usually valid for something like 90 days, but the app token is usually only valid for a matter of hours. – alilland Jul 10 '21 at 04:42
  • 1
    when you have to use the refresh token, you will give the client the new token and save the new token to the database, deleting the old token – alilland Jul 10 '21 at 04:43
  • 1
    Ok I think I understand, so the google api provides me a "userID" of sorts called "sub" and is about 20 characters long. But I'm going to be storing the actual access-token (jwt) in the database, not the "sub"? – Max Jul 10 '21 at 04:50
  • 1
    you can save whatever additional details you want to, but if the user needs to query the google API they need that access token, the sub is the "Subject Identifier" https://stackoverflow.com/questions/32510679/getting-users-token-subject-identifier-sub-from-within-azure-ad – alilland Jul 10 '21 at 04:55
  • 1
    Ok that makes sense, thanks for all of your help! – Max Jul 10 '21 at 04:58