Sign In With Google - Trigger sign in programatically instead of button - google-signin

I'm trying to migrate to the new Sign In With Google and I'm missing one crucial functionality I was using previously.
Basicly my application is working with locally created application users. At one point in the application, the user is prompted to login with Google Account to confirm that he's the correct user that will do some Google API action. I was able to achieve that with following code from the soon deprecated Google Sign-In library:
const auth = gapi.auth2.getAuthInstance();
if (!auth.isSignedIn.get())
await auth.signIn({
prompt: "select_account",
login_hint: employeeEmail
});
...
And it worked just fine. Now all the above methods are being deprecated and there are no direct replacements, or at least I don't understand how to achieve the same result. I am able to confirm the user identity by checking the id token received by using:
google.accounts.id.initialize({/*options*/);
...
google.accounts.id.prompt();
But if there's no google session active for the user, nothing happens.
The only way to actually trigger the Sign In is to click the Google Sign In Button, rendered using:
google.accounts.id.renderButton(htmlElement, {/*options*/});
After the button is clicked, the sign in popup is shown and everything is fine, the callback of the initialize configuration is called and the flow is resumed.
The problem is, how do I trigger the Sign In popup programatically? All of the above starts with a specific button click on my website.

FYI
I actually managed to reproduce almost the same behavior with the new API. It might not be the most elegant way of doing this, but I replaced the signIn method from my post above with google.accounts.oauth2.initTokenClient. Even though it should be used to only receive the tokens, it will also create a valid Google session that then can be detected by using silent auth (prompt: "none");

Related

Google OAuth conditional scope, requestPermissions

I am using the Meteor Account package for OAuth login with google.
My use case is to allow users to login with google. And later, provide them options to opt for linking to Google calendar.
i.e by default I need only email/profile scope during login. And, when the user clicks the button inside the app ( like Update events to my Google calendar ), I want to get the permissions for accessing https://www.googleapis.com/auth/calendar.events.
One option I figured out is to call LoginWithGoogle the second time with the requestPermissions.
My questions are,
Is this the correct way?
If so, how do I prompt the user to provide permission ( without further button click) if the user is denied or revoked this access later point? i.e when getting 403 - insufficientPermissions error.
What are the exceptions that I need to take care of?
Your help is highly appreciated.

how to use firebaseui-web autoUpgradeAnonymousUsers?

How to use firebaseui-web autoUpgradeAnonymousUsers?
Situation:
Before a user is signed-in / logged in, this page could be rendered. However, after a user is signed, I could no longer display this page using the same sample code as https://github.com/firebase/firebaseui-web.
I have set autoUpgradeAnonymousUser: true. So what are the steps to use autoUpgradeAnonymousUser. It is not available in the demo app source code.
Before rendering FirebaseUI, you could call firebase.auth().signInAnonymously() to sign in on the Auth instance. And then pass the Auth instance to firebaseUI instance. If autoUpgrade config is turned on, when user click sign-in buttons, it would trigger the account linking to link google/facebook/password account to your anonymous account. However, you need to provide the SignInFailure callback in case there is merge conflict. Here you can find more detail and code sample: https://github.com/firebase/firebaseui-web#upgrading-anonymous-users

Firebase Auth on Web - How to add spam protection for email/password login

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.

How to log out / change account of telegram after logging in with the Login Widget

I started using the Telegram Widget API, and it works great, but I couldn't find any info on how to logout an user afterwards.
This might be useful if the user decides he wants to use a different telegram account.
Once you click the login button you get redirected to oauth.telegram.org, and if the authorization is already given you won't have the chance to logout.
The only way I found to work is the obvious approach of manually removing the cookies set to oauth.telegram.org, or to click logout on the top right corner of the authorization page, that won't show up if the authorization was already given...
SampleBot Login
By checking the code you can see how the logout is performed:
Logout function
However, you would always need that hash for the link to work.
Then you always have the option to disconnect from telegram itself:
Telegram disconnect
Is there any programmatic way to achieve this?
Thanks

How to get Google Sign-In for Websites to work with Identity Aware Proxy

I have a web site in google cloud. I use Identity-Aware Proxy (IAP) to protect it.
When a request comes in IAP checks if I'm authorized and then responds with either
if I'm authorized: the response from the resource I requested
if not: a 302 or 401 response depending on if it thinks it is an ajax call or not
Now I want to use Google Sign-In for Websites on top of this.
This might seem redundant since I am already logged in by the time I would see the buttons but I want to use it as a way to log out or change user account.
Now what I have tried to do is:
var auth2 = gapi.auth2.init({
client_id: 'mykey.apps.googleusercontent.com',
})
auth2.isSignedIn.get()
// false, I was hoping that I could somehow piggyback on my existing session
auth2.signIn()
// shows a pop up, allowing me to select an account
auth2.isSignedIn.get()
// true
currentUser.getBasicProfile()
// works
This seems to work except it shows me a login box even when I'm already logged in which is suspicious.
Add to this that when I do
auth2.disconnect()
auth2.isSignedIn.get()
// false
and then do a full refresh then I still get my resources from IAP proving that I'm still logged in there.
Questions:
How can I get this to work?
Is this even the correct way to do it?
I don't know much about Sign-In for Websites, but there's another option that might work for you. Have you considered adding a link to /_gcp_iap/clear_login_cookie to provide a "change user account" option? (It's documented here: https://cloud.google.com/iap/docs/special-urls-howto )
If the user is logged in with multiple Google accounts, that will bounce them back to the account picker. Today, if they're only logged in with one account, it will just send them right back into the application -- but there's an enhancement rolling out next week which will display the account picker even for the single-account case, giving the user a chance to sign in with an additional account.
Hope that helps!
--Matthew, IAP engineering lead

Resources