I am implementing Google Sign in in my VueJS App and I have a few questions before starting:
How to create a user when a user clicks on Google sign in button?
Do I have to create a custom route just for that?
Do I have to generate a random password because it is mandatory?
When a user is already registered and clicks on Google Sign in.
Do I have to pass Google Token from Vue JS to Symfony, then with google API, verify if token is valid and generate a token from my symfony application?
If you have some good documentation, I'll take it.
To get this started, it's actually a relatively complicated functionality to implement. This is because you'll have to use custom (maybe multiple if one can both login with Google account or register to your own website) guard authenticators. Moreover, you will need to use an OAuth bundle like KnpUOAuth2ClientBundle or HWIOAuthBundle.
The answer to your questions:
You have to create a custom route for that but you do not need to generate a random password, you can just make password nullable and add checks that it is null only for users logged in through Google (if it's not possible for you then just add something random as password). Additionally, I would propose to add a field provider to your User entity if you are providing both google and your own authentication. You should set this to 'google' or 'website respectively.
The user authentication process is being handled by Google and you are getting an access token as response that contains user's information like name, email etc, so you do not really have to worry about validating passwords etc.
This article helps you get started with KnpUOAuth2ClientBundle.
Related
What I want
I have a list of people with all their personal information (name, first name, date of birth, email, etc.). I created an account for each of these people using their email/phone + a password I generated for them.
I want to send to each of these people an email/SMS with a link allowing them, once clicked :
to be directly connected on our website, without having to type a password or using a third party as Google/Facebook/etc.
and I want the link not to expire after the first use. The user must be able to click on it several times and be connected to our website each time.
What I tried
This is what I tried so far, unsuccessfully :
Passwordless Auth with email link: using both backend and frontend. Doesn't fit my needs because the signin link works only once by design.
Create a custom token with Firebase: as I understood, the token will expire 3600 seconds after creation, which is not useful for me.
Implement anonymous auth: it still need the user to type email+password at some point if you want to convert the anonymous account to a permanent account (because I don't want to use Google/Facebook/etc auth). Plus, it will need consequent changes in all my website code to work.
At this point I realized that Firebase doesn't have a solution that fits my needs. I started to fiddled around as best I could.
The idea
It works as the following:
First I create an account for the user in Firebase + a unique document in a collection in Firestore. That document contains 3 fields: magic_token, email, password.
Then, I create a link to our website with a unique token as a parameter in it. I store the token as magic_token in the document I described above. I send the link to the user.
The user clicks on the link, get redirected to my website. In the front, I detect the presence of the token in the parameters of the URL, I retrieve the document in Firestore with the corresponding token.
Using the email and password stored in this document I call: signInWithEmailAndPassword() to login the user.
PROS:
it fits my needs.
it is easy to implement
CONS:
the user password is visible in Firestore.
it's not very secure.
The question
Is there a proper way to implement a Magic Link that fit my needs? If not, how can I improve my own custom token authentication ?
I did some research and experiments on integrating LINE login with Firebase Auth using Flutter. I have some questions:
Looks like in Firebase Auth, there are AuthProvider, and in Flutter source code, I also found an OAuthProvider. There you can create Credential to include your idToken and access token. But I don't know how to specify the providerId in that Credential. I guess it is not possible, because Firebase hasn't integrate LINE login. The client side api: logInWithCredential can ONLY work with Firebase supported login methods, and you have to enable them in your Firebase console. Am I right?
So it looks like now I have to setup my own server to exchange LINE access token to Firebase custom token. In my server, I first verify access token and grab the LINE user profile, then I create a custom token, but there I have to decide a UID, which I have to use some pattern like LINE:${LINE_UID}. This looks like some hacking, is there a better way?
Admin API to create custom token only accept UID or optionally a user claim, I have no way to set its display name or some other basic info. So if I directly send the token with UID like LINE:${LINE_UID} to a client, then the client logInWithToken, it will create a user without display name if it doesn't exist. The only workaround I can image is, in the server-side, generate the LINE:${LINE_UID} and look up it in Admin API, if it doesn't exist, then I create a user with a proper display name. This looks again not so good, because the document said if you do logInWithToken, it will create one if it is not there, and we cannot use that because I want to set it's display name when it is created. Any better solution?
I want to link a user with multiple auth provider. I saw in the Firebase JWT, they are well included, that is cool. But those linked elements are user profile get via credential. So can we link a user to a LINE login? Which is not built-in Firebase Auth Provider? Is auth provider linking only valid for Firebase built-in provider?
Regards,
Xiang.
You're asking way too much in a single post, which makes it hard to help. I'll try to address below, but please follow the advice on How do I ask a good question going forward.
The general approach for adding LINE as an authentication provider is shown in this blog post: Authenticate your Firebase users with LINE Login. There is also a example, which shows how to use Cloud Functions as the server component for this. If you get stuck implementing those for Flutter, post the minimal, complete/standalone code that reproduces this issue.
The client side api: logInWithCredential can ONLY work with Firebase supported login methods, and you have to enable them in your Firebase console. Am I right?
Nope, you're wrong. You can also provide your own sign-in provider for Firebase, and use the tokens you mint there with the Firebase Authentication SDK.
This looks like some hacking, is there a better way?
The UID can be whatever you want, but you'll have to ensure it is unique. A common way to ensure global uniqueness is to embed some identifier for the provider in the UID. If you prefer another way to ensure global uniqueness, you're free to use that too of course.
I have no way to set its display name or some other basic info [when creating the account]
This is indeed a common problem with some providers, as you for example can't set the display name for the email+password provider until after the account has been created. With a custom provider you can put whatever information you want in the initial JWT already though.
can we link a user to a LINE login? Which is not built-in Firebase Auth Provider?
See Linking custom auth provider with Firebase
Late to the party .
but This article helps you which I publish on Medium.
I'm using A Flutter plugin LINE's native SDKs in Flutter apps with Dart. The plugin helps you integrate LINE Login features in your app. You can redirect users to LINE or a web page where they log in with their LINE credentials. package
Also, I make a git hub repo for the same.
Did you check out the firebase_auth plugin? It has lots of helpfull features.
https://pub.dev/packages/firebase_auth
For my website, I want to build my own login form for email/password based authentication using Firebase authentication instead of using FirebaseUI Web. I'll be using createUserWithEmailAndPassword JS function to create new user accounts. But how can I prevent spam registrations? Usually for web based forms, I would use Google Recaptcha and validate the recaptcha on my server. But here, I'm not using my server for creating the user accounts. I'm making a call on the client side to create the user accounts.
Of course, I'll be using email verification in the flow, but how would I prevent bots from creating the accounts in the first place?
I also understand that Firebase has some sort of limit for the number of requests per min from a single IP, but I would like to go further and try to prevent those registrations.
firebase.auth().createUserWithEmailAndPassword(email, password).catch(function(error) {
// Handle Errors here.
var errorCode = error.code;
var errorMessage = error.message;
// ...
});
Thanks.
After 2 years, this question is still valid and as far as I see, it is not possible. You probably do not need an answer to this question anymore but it may help others. Even if you succeed in doing something manually, those js functions will stay there and can be called manually by any user who knows how to do it.
If there are no hidden, top secret options which are not available in the documentation, this is not possible. There is a recaptcha option but it is only for Phone Authentication. So, it seems like you have 2 options.
Ignore and delete users who do not verify their email address.
Disable email option from Firebase console and implement your own
email authentication. Generate your own token and log user into
Firebase with that custom token. https://firebase.google.com/docs/auth/web/custom-auth
I'm following up on frankish's answer. He is totally correct, and I agree I think it's strange that Firebase automatically integrates ReCaptcha when doing phone authentication (and now when doing Phone MFA), but does not provide support in createUserWithEmailAndPassword for passing a recaptcha verifier. Thus, the only way to really get around this is to do something like the following:
Set up ReCaptcha (either V2 or V3) manually on your signup page. Do NOT use firebase. auth. RecaptchaVerifier, that is only for integration with phone authentication.
Immediately after calling createUserWithEmailAndPassword, you need to make a call to your own server that passes up the recaptcha token. There is a Firebase blog post here about how to do that with a Firebase Function: https://firebase.googleblog.com/2017/08/guard-your-web-content-from-abuse-with.html. Note I think it's a bit strange that Firebase documented how to do this with server-side functions but didn't directly integrate this with account creation.
The final point is that in your server-side code, after you make the call to validate the recaptcha token, you need to set a custom claim on the Firebase user with the Firebase Admin API. That claim can be something like recaptchaPassed: true (or false). For details on custom claims see https://firebase.google.com/docs/auth/admin/custom-claims.
After that, you can then do things based on the value of that custom claim. For example you could read that custom claim in other server-side calls, or you can use it in Firestore security rules (good blog post on this, https://medium.com/google-developers/controlling-data-access-using-firebase-auth-custom-claims-88b3c2c9352a). You could also choose to immediately delete the user server-side (using the admin API), if recaptcha verification fails.
Note it's important to understand that there is nothing that guarantees that some malicious script will call your server-side token verification function after the code on the client calls createUserWithEmailAndPassword. Thus, the only way the rest of your code can guarantee that a particular Firebase user passed recaptcha verification is by looking for your custom claim that you set on the user server-side.
We have a custom app hosted in Firebase (Google's Backend as a service). We would like to use Shopify's authentication so the user doesn't have to create an account in the app as well as the Shopify store (where we require accounts).
The key: I need to have some mechanism (like an API) that I can use to have Shopify authenticate a user. (Assume the customer has already created an account in the Shopify store. Account creation will be handled by the normal Shopify process.)
I can create a page in my app to ask for email / pass. Is there some way to send this info (perhaps along with some sort of token generated from a private app) to authenticate the customer? I just need Shopify to confirm whether the email / pass is correct, so I can then 'login' the user into my Firebase app.
Any direction / thoughts / suggestions are greatly appreciated.
PS. Firebase offers a 'custom authentication' option, along with email, Google+, Facebook. The custom auth option requires sending user / pass to the authentication server, which in this case, would be Shopify.
EDIT: Based on the responses, edited to clarify that I need some way to authenticate the user in Shopify. Handling the custom auth into Firebase seems like a fairly straightforward task, once I receive some sort of signal from Shopify telling me the users email / pass is valid.
This is a classic use case for custom Auth with Firebase. You send email/pass to your backend, authenticate with shopify, on success create a custom token with the user's id (most likely using shopify's user id), send it back to the client which would signInWithCustomToken signing in to Firebase.
Customer logs in to Shopify
Logged in Customer has an ID
Use App Proxy in your App to accept this ID using a secure callback
Use the Shopify API to look up the customer with the secure ID
If customer is found, they are then authentic and can use your App
Why is that not a useful and simple pattern for you to use?
You should take a look to Shopify MultiPass. Although, you need Shopify Plus that is very expensive.
If I create a new product, use simple auth, there is a "create user" API. How do I restrict it so that only invited emails (either by the email or via a one-time key) can sign up? Doesn't seem to fit easily into the rules, but I am probably missing something.
First, I should point out that the core Firebase API uses JSON Web Tokens for auth, which you can generate yourself, so you have full control over the creation of user accounts and can restrict it however you like:
https://www.firebase.com/docs/security/custom-login.html
I'm guessing you're referring to our Simple Login service.
Simple Login is a service that provides some common login options. It has no way to restrict creation of new accounts. However, you can restrict what those accounts can do with Firebase. For example, you could set your security rules up so that only user accounts in some authorized list (in Firebase) are actually able to read or write data.