auth icon indicating copy to clipboard operation
auth copied to clipboard

Link Multiple Auth Providers to an Account

Open sandbox-apps opened this issue 3 years ago β€’ 35 comments

https://firebase.google.com/docs/auth/android/account-linking

sandbox-apps avatar Jul 26 '21 05:07 sandbox-apps

I think this would be great as well

rodjoseph avatar Jul 27 '21 09:07 rodjoseph

Hey @sandbox-apps - this is technically possible, as long as the user has the same email for all accounts (since this is the primary login mechanism).

For example

Both of these will return the same user uuid.

Is that what you're looking for?

kiwicopple avatar Jul 28 '21 11:07 kiwicopple

Firebase has this setup where Example:

  1. I signed up via email/password then login on app
  2. Go to my profile then link social for example facebook
  3. Even though facebook has different email address it can be linked

Another example:

  1. I signed up via email/password then login on app
  2. Go to my profile then link social for example twitter
  3. Even though twitter has no email address it can be linked (via uid and providerId) see here: https://github.com/supabase/supabase/issues/2853

Result:

  1. I can sign in via email/password
  2. I can sign in via facebook and it will not create another account because it is already connected to a user even though they different email address returned during OAuth
  3. I can sign in via twitter and it will not create another account because it is already connected to a user even though twitter has no email address returned during OAuth

Things also that we can keep in mind that..

  1. If a user signed up with email/password with an email of [email protected], user can still create an separate account via facebook/twitter if this social has the same email.
  2. Unless link or merge, then it will create new account.
  3. You can only link account if there is a user that is currently logged in on app/system to determine where would you append the additional data

sandbox-apps avatar Aug 17 '21 04:08 sandbox-apps

Further more you can unlink provider via providerId with the currentUser

Firebase.auth.currentUser!!.unlink(providerId)
        .addOnCompleteListener(this) { task ->
            if (task.isSuccessful) {
                // Auth provider unlinked from account
                // ...
            }
        }

sandbox-apps avatar Aug 17 '21 04:08 sandbox-apps

I would love to have the workflow you describe @sandbox-apps!

It seems the "perfect" way to manage auth with 3rd party providers.

eMeRiKa13 avatar Nov 04 '21 15:11 eMeRiKa13

Hey @sandbox-apps - this is technically possible, as long as the user has the same email for all accounts (since this is the primary login mechanism).

For example

Both of these will return the same user uuid.

Is that what you're looking for?

Hi @kiwicopple, thanks for all your teams great work in supabase, lovin' it! Just want to mention that it would be great if we can link different provider to same account even if the email is different. Sometimes user use different email for different providers. And also able to unlink will be great if user want to have separated accounts event the email is the same. Thanks :)

didavid61202 avatar Dec 06 '21 09:12 didavid61202

For anyone wanting to support this, you'd need to propose to https://github.com/netlify/gotrue as that is where the logic behind users and providers live. I don't know if Supabase runs a fork of it, but this is where the request should be going to

firatoezcan avatar Dec 16 '21 06:12 firatoezcan

Adding another use case here, besides multiple auth paths: I want to store connections to 3rd party apps, e.g. a Twitter connection for retrieving a user's tweets. Else, I need to duplicate a lot of the OAuth logic and store it separately.

henningko avatar May 10 '22 09:05 henningko

Any updates on this

diogoribeirodev avatar Aug 14 '22 23:08 diogoribeirodev

Hi everyone, we currently don't have plans to support manual linking of accounts in the near future. Currently, gotrue only supports automatic linking of accounts based on the user's email.

kangmingtay avatar Sep 14 '22 13:09 kangmingtay

This could be done theoretically with a procedure and policies that updates the auth.users and auth.identities tables.

  • You would basically delete the identity id in auth.identities, remove the provider in auth.users.raw_app_meta_data and auth.users.raw_user_meta_data.

Adding it would require logging out and back in with the provider assuming the email is the same. If you wanted to take that a step further, you could create another procedure with an http function that runs the full oAuth 2 protocol, then saves it manually. You could also theoretically add the missing option for signin with popup.

Of course, if someone does either of these two options, please share the code here.

J

jdgamble555 avatar Sep 28 '22 13:09 jdgamble555

Hey everyone, we're aware of the need to customize the account linking logic and have some plans to make it happen via web hooks / triggers. However, this is not something we're going to be working on in the short term.

I'll be closing this issue as account linking is supported if the user has the same email in the social login providers.

hf avatar Sep 29 '22 11:09 hf

I don't get the point of closing this and stating that account linking is suppoerted when its the same email but the point of this whole thread is to get support for when its NOT THE SAME EMAIL. Its a must have future in auth now and days. This should really be pushed up the priority list.

rlee1990 avatar Feb 11 '23 03:02 rlee1990

This is really a necessity for auth to be functional in a lot of cases. Automatic linking is too unpredictable and doesn't address the issues described here.

sdaoud avatar Mar 06 '23 17:03 sdaoud

Hi @rlee1990 and @sdaoud, I've pinned this issue to emphasise that this is definitely one of our top priorities going forward and we're working to make this happen gradually. If you've been keeping up with the updates on Supabase and gotrue, you may already know that automatic linking has always been the default way that gotrue links accounts. While we understand the advantages of manual linking that have been discussed in this thread, it's important to keep in mind that removing automatic linking altogether could create backward compatibility issues for existing users.

Furthermore, we've received feedback from many developers who appreciate the simplicity of automatic linking for UX purposes. While we recognise the benefits of manual linking, it's not something that we can expect everyone to switch to overnight.

I also want to reiterate that we'll eventually move to the model of manual linking accounts through a well-designed API. Currently, we are considering a few ideas to implement this:

  1. Implement some form of webhooks so users can define the linking behaviour between accounts
  2. Provide an API to support the following:
  • link newly created identities to existing users
  • unlink an identity from a user

@hf has already made some progress to simplify the account linking logic in this PR to make way for the use of webhooks to decide linking behaviour. Please feel free to drop any ideas you may have regarding this topic too as the team will be more than happy to discuss them in detail!

kangmingtay avatar Mar 09 '23 04:03 kangmingtay

@kangmingtay using a webhook sounds like a nice approach. I get keeping automatic linking in place also. A webhook to help link an account is a useful option.

rlee1990 avatar Mar 09 '23 04:03 rlee1990

I would say keep the automatic linking as the default option, but add a simple config option automatic linking: true that could be set to false.

Then just copy the ideas of link and unlink that Firebase uses or Auth0. Basic functions seem to be a good idea.

J

jdgamble555 avatar Mar 09 '23 04:03 jdgamble555

@jdgamble555 we thought of that option too but it's not feasible to make it toggle-able since automatic linking requires the email to be unique for the algorithm to know which user to link the new identity to. For example:

(assuming automatic linking: false)

  1. User 1 signs up with [email protected] using google
  2. User 2 signs up with [email protected] using facebook (not linked to (1))
  3. Toggle automatic linking: true
  4. User 3 signs up with [email protected] using twitter (no way of knowing whether to link User 3 to (1) or (2))

It has to be a one-way toggle or an option you select before you start building your app. Either you opt-in for automatic linking or resign to a manual linking API for eternity πŸ™ƒ

kangmingtay avatar Mar 09 '23 04:03 kangmingtay

Hmmm, I definitely don’t like the eternity issue. 🀷🏻 Perhaps the simple answer is to automatically link with the first found profile, in reality the first document id record containing that email.

Any new profiles going forward would be automatic, but all profiles would have a link and unlink option after sign up. This puts the control back into the developer. So that boolean option is only concerning new signups, and the first found option. This solves any backwards compatible problems.

Linking is always available.

I should add this is also relevant for anonymous logins too, which is an entirely different feature.

πŸ˜ƒ J

jdgamble555 avatar Mar 09 '23 05:03 jdgamble555

@kangmingtay @hf Can you explain what modifications are needed to be done in the database to link two accounts together?

ofekd avatar May 03 '23 22:05 ofekd

Hello,

we need to achieve something similar. We have an app where the users, logged by social logins or not, could add other auth providers accounts with additional scope. The other accounts could be from the same auth provider.

Example: I'm logged in my Sales CRM as [email protected] with access to my contacts, then I want to import contacts from my other gmail account named [email protected] without creating another account but linking the latter to the first.

As a quick (and dirty?) workaround, we have overriden Gotrue callback URI to point out to our backend. This way, we could either fetch token and do our business or redirect users back to Gotrue for user account creation.

Is it something planned to implement?

baderdean avatar May 23 '23 12:05 baderdean

this is very important to use as well ... would help cross-device sing-ins ... for ex if i sign up / sign in with apple ... i will not be able to use that account in a non-ios enviroment

empato-limited avatar Aug 12 '23 14:08 empato-limited

is there an estimation when this will be addressed?

aaroniker avatar Aug 13 '23 00:08 aaroniker

This seems to be a must-have feature for any auth solution. What site nowadays doesn't even let you connect multiple oauth providers with different emails?

sebmor avatar Oct 07 '23 20:10 sebmor

Ah this just managed to kick me off of using the auth system in Supabase for a project; really wish a link function existed :(

ARMATAV avatar Oct 23 '23 02:10 ARMATAV

@hf any update on this? πŸ™πŸ™‚

aaroniker avatar Nov 14 '23 17:11 aaroniker

We are working on it! Sorry for the delay... it's not a simple feat as we need to make sure not to break any existing behavior, while allowing for an API that we won't have to go back to in 5 months time.

hf avatar Nov 14 '23 22:11 hf

We are working on it! Sorry for the delay... it's not a simple feat as we need to make sure not to break any existing behavior, while allowing for an API that we won't have to go back to in 5 months time.

@hf Thanks for the update, that's awesome!! ✨ any rough ETA?

aaroniker avatar Nov 19 '23 18:11 aaroniker

Hey everyone, just an update, we've merged in 2 PRs that will make manual linking possible very soon:

  1. Link an oauth identity to a user: https://github.com/supabase/gotrue/pull/1317
  2. Unlink an oauth identity: https://github.com/supabase/gotrue/pull/1315

We'll need some time to roll this feature out to all projects on Supabase but if you are self-hosting, you should be able to use this new feature with the latest version of gotrue. The target ETA for getting this out to all projects is by LWX

The corresponding client library bindings will also be added to the js library in this PR: https://github.com/supabase/gotrue-js/pull/814

The process for linking / unlinking an identity will look something like this:

// assume user is already logged in and authenticated

// link the current user to a google identity
// this works very similar to signInWithOAuth() and will redirect the user to google to complete the oauth flow 
// once the oauth flow has been completed, the user will be redirected back to the app with the identity linked
const { data, error } = await supabase.auth.linkIdentity({ provider: 'google' })

// fetch all identities linked to the current user
const { data: { identities } } = await supabase.auth.getUserIdentities()

const googleIdentity = identities.find(identity => identity.provider === 'google')

// unlink an identity
await supabase.auth.unlinkIdentity(googleIdentity)

kangmingtay avatar Dec 01 '23 19:12 kangmingtay

This plus a fix for expiring tokens in @supabase/ssr will be a life saver

ARMATAV avatar Dec 02 '23 18:12 ARMATAV