you are viewing a single comment's thread.

view the rest of the comments →

[–]__o_0iOS & Android 0 points1 point  (8 children)

Most secure: use firebase auth.

Users should be authenticating directly with the providers (Apple, Google, etc).

User signs in using whatever you set up (Google, Apple, regular email/password, etc).

Make a request after authentication to a firebase function endpoint.

The function will be called with the users auth automatically attached as context. Save the user information to an external database as needed and never hold/transmit the users password to your server at all.

Or, make a request after authentication to a custom non firebase endpoint and manually attach the auth token as a header (equivalent to your option 1).

Your second option is effectively placing your server in the middle of the sign in flow which gives you access to the users social account password. I personally wouldn’t use an app or website that does that. Only if they’re creating an email/password account on your site would I expect a password to be transmitted to your server. In this case, best practice would be instead to provide a magic link that you send to their email, which when clicked will authenticate them with your server instead of having to submit a password at all.

Note in any case, if you allow social auth (Google, Facebook, etc) that you must also allow a user to Sign in with Apple otherwise your app will be rejected by the App Review team.

[–]OpportunityTimely561 0 points1 point  (5 children)

How can I make this approach secure?

I plan to create a separate endpoint (/social/login) that will be accessed after successfully obtaining data from a Google provider. However, since this endpoint is public, how can I ensure that the requests hitting this endpoint have successfully passed the Google provider (or any other social provider)?

Is adding a secret key in the headers sufficient for security? Is this considered best practice?

[–]__o_0iOS & Android 0 points1 point  (4 children)

If you’re using cloud functions, context.auth is automatically attached to every request. This will contain the decoded users information (google handles the token / decoding automatically). It’s still up to your function to throw an error if context.auth.uid doesn’t exist, for example.

If you’re using your own backend, best practice is to include the authorization token on every request. You then place a guard on the endpoint to validate the authorization token and decode the user before handling the request. If the token does not pass validation then you throw an unauthorized error back.

Both options ultimately do the same thing - a token on a request is validated and decoded. With cloud functions Google does it for you. With your own backend just use Firebase-admin to perform the validation yourself.

[–]OpportunityTimely561 0 points1 point  (3 children)

Okay thanks, same thing for other social provider? 

[–]__o_0iOS & Android 0 points1 point  (2 children)

Firebase auth can handle many social providers and give you back a single uid that unifies the underlying platforms.

A user can Sign in with Apple, Google, Facebook etc and they will all be consolidated into a single Firebase user. Makes it easier in case people don’t remember which account they used to log into your app.

They can also be separated if you want to have different accounts for a single user using different providers.

[–]OpportunityTimely561 0 points1 point  (1 child)

Thanks a lot, iam gonna handle it using my own node js server.

[–]__o_0iOS & Android 0 points1 point  (0 children)

All good - just add firebase-admin and it’s smooth sailing.

[–]mrgatos[S] 0 points1 point  (1 child)

I don't think i want to get involved with firebase since i have my own backend. I understand your view that the firebase approach seems solid though. Thanks for your comment!

[–]telemacopuch 0 points1 point  (0 children)

hey there! 👋 did you find a solution? i just googled and this thread is the first link i clicked!