Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to solve this Timeslot issue in C#

Tags:

c#

asp.net

I am trying to solve this business issue:

  • A user gets 10 attempts to login every 5 minutes
  • If a user exceeds 10 attempts, I display a "You need to wait to login" message
  • Once 5 minutes have elapsed, I need to reset the number of attempts and let the user attempt 10 more times.

I'd like to do this without using a Timer and I am storing most of this info in the Session

public class LoginExp
{
  public DateTime FirstAttempt;
  public int NumOfAttempts;
}

I store the FirstAttempt DateTime on Page Load.

On the Login button click:

  • I increment NumOfAttempts
  • I need to check if NumOfAttempts < 10 within the same 5 minute time slot. I could get the number of minutes elapsed between FirstAttempt and DateTime.Now and do a mod of 5, but that won't tell me which timeslot this is in (In other words, a user may have attempted 3 times as of the 2nd minute and then comes back in the 7th minute to do an attempt again. The mod would give me the same value.

Any thoughts on how I could do this?

like image 454
DotnetDude Avatar asked Nov 02 '12 16:11

DotnetDude


2 Answers

Don't use a timer, please. Make room for this data alongside the user data, to be persisted, where some form of their credentials is stored. Just keep a last login attempt time and number of attempts - if the time is greater than n then the next attempt clears the previous count and starts from 0, and so on.

like image 129
Grant Thomas Avatar answered Sep 30 '22 19:09

Grant Thomas


You could store a list of attempt timestamps and use that to determine if the user is locked out. This is not complete code, but here's the basic idea:

// Store a list of attempts
var attempts = new List<DateTime>();

// Determine if 10 or more attempts have been made in the last 5 minutes
bool lockout = attempts.Where(a => (DateTime.Now - a).TotalMinutes <= 5).Count() >= 10;

// Register an attempt
attempts.Add(DateTime.Now);

// Remove attempts older than 5 minutes
attempts.Where(a => (DateTime.Now - a).TotalMinutes > 5).ToList()
    .ForEach(a => attempts.Remove(a));

You could also store the attempts in a database, which would give you a papertrail for security purposes. The same methodology would apply -- count the records less than 5 minutes old.

like image 35
Jon B Avatar answered Sep 30 '22 21:09

Jon B