On my Meteor site, users can log in using an OAuth authentication from a particular provider (vKontakte). After logging in, on a special page of my site users can specify also their email address to receive notifications. Obviously, I want to verify the address before any notification sent.
Standard instructions for email verification that I find in Meteor docs and in other sites use accounts-password package. That's OK, and I can call sendVerificationEmail() from my email update code, but the problem is that accounts-password also adds possibility for local (non-OAuth) registration. My site is rather tightly coupled with the OAuth provider, so I do not want to have any other way to login to my site except via this OAuth provider, and so I do not want to have accounts-password package on my site. Or at least I want accounts-password to have no effect from the user point of view except the possibility to send verification emails (no register buttons etc.)
Is there any way to send verification emails without accounts-password package? Or to disable all accounts-password functionality except email verification?
Of course, I can implement email verification completely manually (generate a token, send an email, setup a route for verification), but if there is some more standard way to do this, I'd better stick to it.
I finally solved this by copying the accounts-password.js file to server/lib and removing all code that I did not need. I do not like this solution because if accounts-password wil be updated, I will have to update my file manually, but I see no other way to do this.
I am not sure that all of what you are describing is needed. Granted, the code would exist on the server, but if you were to add accounts-password and call sendVerificationEmail() there is really nothing to say that you will have to have the signup and password functionality that it allows. Are you using the accounts-ui-unstyled to handle the front end portion of the accounts? If so, you can simply not give the user the ability to see or use the functionality you don't want them to have.
Related
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.
I have a Chrome extension that communicates with my Meteor app through a REST API created with the Restivus package.
The user authenticates to the REST API and then uses authenticated tokens to make any further requests.
So far, everything works fine, as long as he stays within the extension. However, from the chrome extension, I'd like to redirect the user to his profile page on my main website. When that happens, he's no longer authenticated, and must re-sign-in to access the profile page.
I figure this is because the REST API session and the webpage session are two completely different sessions on the server (even though both the API and the webpage run from the same server). My question is, is there a way to maintain the user's logged-in state as he moves from the extension to the main website?
I figure there are a few options:
I'm using the standard meteor accounts package. Is there a way to push whatever standard cookie / data that the accounts package uses, to the user's browser, so that when he goes to the website, he'll be considered logged in?
Push a custom cookie to the user, which I then check for and log him in when he first comes to the website. However, I don't know how to push a cookie through a REST API or generate one in the Chrome extension
Use DDP to communicate with the second session and transfer the login credentials.
I don't know if these are the best options (or even how to implement them if they are...). Has anyone figured out a way to do this already? Thanks!
I would suggest you to develop your own flow of authentification using a token as an URL parameter. You should achieve a similar experience that slack provides with magic authentification links
The idea is to generate a token and add it to the Meteor.users collection for the user logged in your chrome extension.
Then, redirect your user to an url with the token as a parameter. The app checks which user is linked with this token and log him in.
You can get inspiration on what is done in the account package to handle enrollment and reset links, or in the passwordless package
I'm using the default settings of the accounts-password package for MeteorJS. Using the default {{> loginbuttons}}, I'm able to add login functionality out of the box. The one thing that doesn't seem to be working is the reset password feature. I've configured the MAIL_URL variable correctly as I can send emails using the email package and when I click on reset password, it pops up on the UI to say that an email was sent. However I am not getting any emails sent to my inbox.
I'd be grateful for any help you give me on this matter. I think it's probably something small I'm missing...
All the best
There is a function that you can call to send this:
Accounts.sendResetPasswordEmail(userId, [email])
http://docs.meteor.com/api/passwords.html#Accounts-sendResetPasswordEmail
Call it from your server code to verify that it works (or not). If this does, it is perhaps something in your styling or html that is preventing it
I am trying to send a verification email to users upon registration. I'm using Accounts.createUser to add users to the database and that works fine without any email verification system. HThen, when I try implementing email verification by using Accounts.sendVerificationEmail, it does not send any email. I have set MAIL_URL and I'm using Mailgun. When I try sending an email within terminal, it sends as expected. I have tried using the process provided here: https://themeteorchef.com/snippets/sign-up-with-email-verification/ where the method is server-side and then I use Meteor.call to call that method but that isn't sending the verification email. I have also tried implementing Accounts.onCreateUser() and calling Accounts.sendVerificationEmail(user._id) from within but that is also not sending the email.
In my server code I have the following in the startup function: Accounts.config({sendVerificationEmail: true, forbidClientAccountCreation: false}); I've also noticed that when I add in any kind of email verification code server-side, createUser fails and tells me the username is not defined but works 100% as expected without any email verification.
Here are some links to various sources I have been trying to use in order to get this working:
verify email using accounts.ui package
https://themeteorchef.com/snippets/sign-up-with-email-verification/
Meteor 1.3 verify email when creating user
I've also been using the Meteor docs but I can't seem to get it working. I also have installed related packages (email, accounts, accounts-ui). Any help is appreciated!
Thank you to #PankajJatav for asking me to read through the server console more carefully! The problem for me was that I am using mailgun as my smtp service. I was using the default sandbox domain when trying to implement my email verification system but the sandbox domain is only for testing purposes. In order to actually get emails sent, I had to go to mailgun and add in the recipients as an authorized recipient. If you set up mailgun with your own domain right from the start, this shouldn't be an issue.
Once again, thank you to #PankajJatav
I'm working on a Drupal 6 module to provide OAuth-based user authentication and registration. I'm already using the OAuth module to authenticate as described on http://oauth.net/core/1.0a/#anchor9. The next step is to create the user account using information provided after authentication using an custom API of the Service Provider.
According to http://drupal.org/node/497612#comment-3047302, I should not use user_external_login_register() but see the OpenID module for how to properly login an external user.
After studying the OpenID module, here is what I plan to do:
Try to load an existing user for a authname build from the custom API result using user_external_load().
If a user exists, use user_external_login() to log the user in.
If not, pretend the registration form has been submitted (like openid_authentication() does) to create a new user account. And redirect to a pre-filled form if any additional information is needed in order for the user to register.
Is this the right way to do it ? Is there another module worth looking at for how to this properly in addition to OpenID ?
You could have a look at the former Drupal module. That module did two entirely different things (hooray for the architecture :)).
* It puplished information to a central "who runs Drupal" directory. (and offered a page to show such a directory yourself!)
* It allowed login with credentials from other Drupal-sites.
The latter is what you are looking for. Note that the module was discontinued, not because the method for logging in was done wrong, but because the DrupalID mechanism itself is flawed. It has been replaced with openID and oauth.
http://drupalcode.org/viewvc/drupal/drupal/modules/drupal/drupal.module?hideattic=0&view=markup
The hooks and methods you would be looking for (in that order) are:
drupal_form_alter -- Adds validate-callback to the login forms.
drupal_form_user_login_alter -- Adds information about alternative login on login form.
drupal_distributed_validate -- Validation callback: calls drupal_auth to see if the user is valid. If so, calls user_external_login_register
drupal_auth -- Helper for validation callback: determines if the credentials are valid.
All other functions are either helper functions for these, or provide that directory-feature, or allow remote sites to authenticate against our database. Neither of which you will be using.