Please help; so I have this working code that shows the user an error (via a dialog box) if they do not enter the credentials I set. But if they enter the correct credentials, it takes the user to the homepage. Now I need to add a limit on the # of failed login attempts.
I also imported DDPRateLimiter, but not sure if i’m doing this right.
What would be the best way to set a limit or a maximum number of failed login attempts? And, can I enter this code within this const Login function I have here? I don’t need anything too fancy
In your code, you save this in the state so if the user refreshes the page, she can retry forever. I would save this on the user’s profile or on a separate collection and give a grace of 1-5 minutes or so. When a user tries to log in I’d first check if the user is entitled to log in and eventually present the remaining time if that is the case.
Anyway, for most cases the link above could be enough.
Hi, thank you, I check out that documentation and was still confused on how to structure the code unfortunately. The code I have above is located in the Login Page, inside the client server. I’m not sure how the documentation code can fit with what I already have.
Do you know where and what to write inside Meteor.startup() in the server side? This is a fragment of my server side:
You can always dig into the “big” Meteor projects to learn best practices especially in the area of App security.
Here’s an example of DDP security implementation:
Sounds good, but how does the client know it works? Like, how can I display a message saying that they’ve reached the max # of attempts? Unfortunately, i don’t see a way to do that in the meteor docs or github
How would I throw an error in the method that detects if the user types an incorrect user/pass more than twice? Which function would I use? It seems that my onLoginFailure is overrided if I use another method, so I’ve tried that, so any guidance would be appreciated
Yes, I did, that’s where I got the idea to use the DDPRateLimiter from. And trying validateLoginAttempt did not work for me. I’m just not sure how to implement it because I’m not sure how to turn my meteor.loginwithpassword into a method, in order to get the DDPRatelimiter to work. I tried to use the code I found on stackoverflow and another meteor-forum post, but it just doesn’t work, sadly
Ah ok, haha this is great, I hope it works, but I also wish Meteor had a simpler solution because DDPRateLimiter didn’t work for me since meteor.longWithPassword can’t be housed inside a method/call
for example when you don’t want user to run a password scan (brute force ) then you can use DDPRateLimiter to limit the number of login method calls in a period of time.
import { Meteor } from 'meteor/meteor';
import { Accounts } from 'meteor/accounts-base';
Meteor.startup(function () {
Accounts.validateLoginAttempt(function (attemptInfo) {
console.log('validate login attemp connection', attemptInfo.connection);
// TODO: check if this client ip address has exceeded failure attempt count then return.
// TODO: then return false to prevent user to login
});
Accounts.onLoginFailure(function (loginDetails) {
console.log('on login failure', loginDetails.connection);
// TODO: increase the login failure count for this client ip address.
});
Oh okay, how do I display this to the client? Because if you scroll all the way up, I have the onLoginFailure in the client. I’m not sure how to test this sorry Like, what did you write next to the //todo when you tested it?
The callback of both Accounts.onLoginFailure() and Accounts.validateLoginAttempt() gets passed an “attempt info object”, which also contains a reference to the user object.
In Accounts.onLoginFailure you could update a property e.g. failedLoginAttempts (of type array) in the user document. You would add a timestamp (such as new Date()) to that array for each failed login attempt.
Unset this property once there is a successful login, eventually.
In Accounts.validateLoginAttempt() evaluate the failedLoginAttempts array of the user document. If the rate of failed login attempts was too high, throw an error that you can recognize as such on the client side, and display an error message to the user accordingly.