accessing Provider(google, facebook, email, phone, etc) specific info from FirebaseUser/FirebaseAuth - dart

In my app the user can sign in/out with multiple accounts like Anonymous, Google, Facebook, Twitter, phone, email.
Moreover, when more than 1 providers are logged in, I use FirebaseAuth linkWithCredential and link the new provider credentials with the existing FirebaseUser.
I am listening to FirebaseAuth onAuthStateChanged() to get sign in/out events and it is working as expected.
However, in the listen method, I would like to differentiate between these providers and be able to disable/enable the different providers sign in/out buttons.
How can I know FirebaseAuth is currently logged in with which providers?
firebaseAuth.onAuthStateChanged.map((FirebaseUser user) {
//do something with the user to understand which of the MULTIPLE providers he/she is currently signed in/out with
});

Related

FusionAuth - Invite based user on-boarding with social logins

We create users with their email address. We send email to each user with a link to change password api with changePasswordId. When user clicks the link, he will be redirected to change password screen where he can set the password and access the application. This works.
But, now we want to allow users to register with their social Idps upon receiving invitation/verification email. Can't see any fusionauth documentation on this part.
Questions are as follows
How to let user select their social Idp while verifying their email?
Can a user have multiple logins with different Idps for one application in FusionAuth?
Is there any linking api which links all external user accounts with their fusionauth user account?
The flow we are expecting is :
Invite User -> User clicks link -> User will be presented with set
password and social logins-> User chooses google -> Google
authenticates user and returns token back to fusion auth -> fusion
auth links user's google account with already created (invited) user
account. -> Next time user logs in with google account -> Fusion auth
identifies the user and allows him to access the application.
Updated :
Let me try to explain our situation and need, with less focus on the password setup task:
We need to set up new users that are associated with google based education accounts on custom school domains. Teachers and students that might have addresses like first.last#middle.school.com We need to take the class roster from Google Classroom, initialize accounts for each student in our backend via our API which also creates FusionAuth user and app registrations for each.
Schools don't often want kids setting passwords on vendor sites. When we send the account confirmation / verification email to the new cohort of students they would ideally be directed to the approved and configured method for that domain (perhaps Google, Microsoft, other SAML or password). If we can't get selective about the confirmation method shown after the student provides her invited email address then we could present multiple confirmation options on the same screen and let the teacher direct the students to the correct choice.
But in summary we need to avoid requiring password setup and support confirmation with the invited social account when required by the school.
If I understand your use case correctly, what you want is to add the "Login with Google buttons" to the Setup Password workflow. This is different than the Email Verification workflow, so if you are looking for a way to log users in with their social profiles during Email Verification, that's something completely different. In fact, I don't think that is a use case because after the user verifies their email, they need to log in again and they can do that using their social profile.
Unfortunately, FusionAuth doesn't fully support the ability to allow someone to use the Setup Password workflow using a social login. It might be possible though using the Email Templates and Theme editor in FusionAuth. I haven't tested this, but you could try it and see if it works.
What you would do is to pass in a URL parameter to show the social login buttons during the Setup Password workflow. This would be something you could do in the email template for Setup Password like this:
Click this link to setup your password:
<a href="https://example.com/password/change/${changePasswordId}?showSocial=true">
Setup Password
</a>
Then, using the Theme editor in FusionAuth, you would add some code in to show the buttons like this (the ?? part is to handle when the parameter is missing):
[#if showSocial?? && showSocial]
show social buttons here
[/#if]
You could give that a try and see if it works for your use case. If it doesn't work, you can always open a feature request for this on our GitHub issue tracker and we can see if it receives enough upvotes to get on the roadmap. You can also engage FusionAuth professional services to build this feature for you as well.
For your other questions, you can have as many logins with external IdPs as you want for a single user. The user is unique by their email address.
I'm not sure what you mean by "linking api", but if a user logs in with an external IdP, their tokens from those external providers are stored on the user object. You can look up those values and then call third-party APIs with their access_tokens.
UPDATE 8/27/2019
Ah yes. The social login buttons do require all of the OAuth parameters, so this solution won't work because those parameters aren't part of the Setup Password workflow.
I guess I'm confused on how this actually works and whether or not this is a workflow FusionAuth should be handling. Social logins aren't generally used for account verification. They are normally used for account creation. For example, you could just send the student to FusionAuth before their account is created, they login with their Google classroom account, and then they have a FusionAuth account. Is there any reason the student can just login in after their account is created? Is that not essentially the same thing?
Could you do something where students that have accounts in Google Classroom are created in FusionAuth with a randomly generated 32 character password (for security) since they will be logging in with Google regardless. You can then just send them an email with a standard login link.
For students that login in with a username and password to FusionAuth directly, send them a Setup Password email. This will let them pick their own password.
In terms of account Linking, FusionAuth links accounts automatically based on email address (the unique login identifier actually). Therefore, you don't need to call any extra API to associate the social login with a user.
I might still not be clearly understanding the use case, so feel free to contact us directly using the form on our website. We might need to setup a web conference to discuss your needs in detail.

Switch account in web app when using Google Sign-in

I've implemented Google Sign-In in my web app and the users should have the option to switch accounts.
Switching accounts would be done basically by logging out, then logging in, but after having the option to select one of the accounts.
However, it seems that whenever the user wants to log in back, they are not prompted which account to select and instead, they are logged in with the one used initially.
So, how can it be done?
You can call signIn with options to control this.
signIn({ prompt: 'select_account' }) is what you want.
select_account
The authorization server prompts the user to select a Google account. This allows a user who has multiple accounts to select amongst the multiple accounts that they may have current sessions for.
See https://developers.google.com/identity/sign-in/web/reference#googleauthsigninoptions.

What is the best way to handle connection to many Twitter accounts?

My application need a twitter account to create an account and authentify. Then, the user can link any other Twitter accounts as he like. So, a user has ONE main twitter account which allow him to connect to my app, then, he can browser all the accounts he has previously linked in the app. My question is about the login process on Twitter side.
First, I've thinked about setting force_login only when linking new account. This way, the user does not have to reconnect on Twitter each time he want to connect to my app. And, when he want to link another account, force_login force him to chose the right account. The problem is that Twitter stay connected to the last authentified account. So, if the user logout from my app just after linking another account, then login with twitter, he login with the second account, and create a new user on my app. Exemple:
User has two twitter accounts : #a and #b. He's authentified to Twitter with #a. He signup to my app, Twitter shows him the permissions asked by my app, user accept, he's redirected to my app, a new User which can auth with #a is created.
Then, he link #b account. Thanks to force_login, Twitter asks him for credentials. User login to #b, Twitter asks permissions, then, the account is linked to the user on my app. We now have a user who can auth with #a and who is linked to #b.
Then, session on my app is over, user needs to reconnect. Because there is no force_login, Twitter sees he's already connected with an account which authtorised my app, so connection is accepted without any action from the user. But, what nobody sees is that user was connected with the last account : #b. So, I get a signin action with #b, which means to a new user creation.
I now have two users : User1 which can auth with #a and is linked to #b, and User2 which can auth with #b. And my user doesn't understand where is its #a account.
So my question is : do I have to set force_login anywhere ? Or is there another way to tell Twitter to not authentify when linking an account?
EDIT for more details :
It's not so easy. Keep in mind that many user should manage the same account. A simple example : #Maurice and #Roy are members of #ReynholmIndustries corporation. They will create their own account on my service with their own account on twitter. So on my service, I will have User1 which can connect with #Maurice and User2 which can connect with #Roy. Then, #Maurice will add #ReynholmIndustries account to my service. So, after login in with #Maurice, he can manage #Maurice and #ReynholmIndustries. Then, #Roy will add #ReynholmIndustries too. Nobody can login with #ReynholmIndustries but #Maurice and #Roy, with their own account can manage it. And then, it's obviously possible that someone create a new user by signing up with #ReynholmIndustries.
The difficulty is when adding a new account : UserA signin to my service by signin in on Twitter. He's now authentified as #Maurice and on my service as UserA and can manage #Maurice. Then, he adds #ReynholmIndustries by signin in Twitter as #ReynholmIndustries. He's now authentified on my service as #Maurice, can manage #Maurice and #ReynholmIndustries but, on Twitter, he's now authentified as #ReynholmIndustries.
Later, he lose auth on my service and he click on signin button. He's redirected on twitter oauth form and we have now two options :
without force_login : he is authentified as #ReynholmIndustries because it is the last account he signin with. So, Twitter don't ask him to auth and he's automatically redirected to my service, but not as UserA who auth with #Maurice, but as a new user : UserC which will auth with #ReynholmIndustries. UserC can manage only #ReynholmIndustries because he's a new user.
with force_login : even if he is auth with #ReynholmIndustries on Twitter side, he will need to give login/pass and he will be sure to chose the correct account : #Maurice, to access UserA and manage the two accounts. But, he will always have to give login/pass everytime he'll have to auth to my service.
By writing this, I realise it is not a problem : if my service had a local auth, user should have too to type login/pass everytime he lose auth… maybe force_login is really the correct option. What do you think about all of this?
For me it looks like your problem is not related to twitter at all. You just need to handle the login / sign up process properly in your application.
Here is what happens, according to your description:
User signs up with #a account
Internally you create the user profile in your database (I assume that you have the database, doesn't really matter what kind of database), like this:
User A
id = 1 (your internal id)
name = UserA
accounts (related table)
twitter #a
User adds one more (#b) account
You update the user profile like this:
User A
id = 1
name = UserA
accounts
twitter #a
twitter #b
The user signs out
The user logs in back with #b account
Twitter approves it and redirects back to your app
Now you say "So, I get a signin action with #b, which means to a new user creation.". Why so? Twitter knows nothing about your application, but you do know it.
What you want to do here is just search through your database, find that you already have the "twitter #b" account and it is linked to "UserA". Then you just login the "UserA" into your application instead of creating the new user (you anyway don't want to have different users with the same twitter account, so twitter account id should be unique in your database).

Adding Facebook register/login to app

So I've done some research to add a register and login feature to my new app. I want to add the following things: Facebook, Twitter and my own register/login options for the users.
I've dived into some SSO from Facebook, looked into some php scripts on how they do it. So basically correct me if İ'm wrong.
User clicks on Facebook button
App checks if user is already in the database with the oath_provide en oauth_uid
If not: User is getting asked by Facebook API for accepting
App submits the oauth_provide (Facebook) and oauth_uid (user id) from the media that they've chosen to my SQL database.
User accepts and logs in to my app.
User is logged in
Same is probably for Twitter. Thanks in advance!

Linking new users signed in via Facebook connect to existing accounts

I have recently implemented login to my via facebook connect. So now users have 2 ways of logging in to the site. The old way of registering an account and the new way (facebook connect).
One thing I would like to do is link a new facebook connect user account to existing accounts if they logged in the old way.
Has anyone had any success doing this?
Very good question I think and lots of people will benefit from an answer.
What you need to remember is that accounts are only linked so long as they are authorised to be linked through Facebook. What you should do is maintain a second table of linked accounts in your database so that you know who is who and if they are linked with Facebook.
You should read this integration comment, it provides a lot of useful information.
http://crazyviraj.blogspot.com/2010/01/test-cases-for-basic-facebook-connect.html
It doesn't really say how to do things, but it makes sure you tick all the boxes of what you should be doing.
ie:
Sign Up should fail if the user denies
permission to the app (category: sign
up)
Since we need access to an email
address, Sign Up should fail if the
user provides publish permission but
denies email permission (category:
sign up)
If the user provides an email address
that already exists in your system,
fail Sign Up. Make sure no YouFace
backend tables are modified (category:
sign up, 1:1 mapping) PS - when this
happens, I didn't find a way for you
to de-authorize YouFace on the
Facebook user's behalf. The user must
manually do this if they wish you use
the same account but provide a
different email address.
Accounts created using Facebook
Connect should not be able to login
using YouFace's default email/password
login system (category: sign in,
account security). PS: Since YouFace
accounts require a password and those
created using Facebook Connect don't,
make sure to insert a random password
hash into your table to avoid silly
errors
Accounts created using YouFace should
be able to sign in without requiring
to be signed into Facebook, even if
when a link to a Facebook accounts
exists (category: sign in)
Any many more
You should be asking for permanent access through fb connect authentication. Once you've done that, you'll get a token which gives your permission to access someone's Facebook information, and that token will not expire unless the user explicitly removes you from the permission list or changes his/her password.
Once you have the token, associate that token with the user / create a new field in your user table to store it.
To associate the user with a Facebook account without the user logging in, you can try to match by email. It's not 100% accurate but it's pretty good. Facebook doesn't give you email addresses in text form but you can get email hashes from FQL. Since you already know user email addresses, you can calculate the hash for all of your user emails and search through your user base for matches every time a new Facebook Connect user signs up.

Resources