my Html code
<asp:TextBox ID="Txtcomments" runat="server" TextMode="MultiLine"></asp:TextBox>
<br />
<asp:Button ID="BtnPost" runat="server" Text="Post" OnClick="BtnPost_Click" />
<br />
<asp:Label ID="Label1" runat="server" Text=""></asp:Label>
my problem is i have a sample webform like this if a user makes a comment it will save in the database but i had to restrict a particular user like that he should make only 2 comments(requests) within 5 minutes of time if the same user wants to make 3rd comment he should be displaying a message
What I have tried:
i have tried like this first I thought like i should restrict the user using ip address so i had done this the problem with this here it restricts all the users of that host not a single user i want to restrict the number of requests from the particular user(say a particular computer or laptop) Please help me to this in what way i can achieve this
protected void BtnPost_Click(object sender, EventArgs e)
{
string ipaddress;
ipaddress = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (ipaddress == "" || ipaddress == null)
ipaddress = Request.ServerVariables["REMOTE_ADDR"];
string SessionID = Session.SessionID;
var Throttle = new Throttler();
if (Throttle.RequestShouldBeThrottled(ipaddress))
{
Label1.Text = "Access Denied because of Too Many requests";
TimeSpan span = (Convert.ToDateTime(Throttler.NextAccessDate) - Convert.ToDateTime(DateTime.Now));
string diff= String.Format("{0} minutes, {1} seconds", span.Minutes, span.Seconds);
Label4.Text = "Elapsed Time = "+" "+"Try Again After "+diff;
}
else
{
SqlConnection con = new SqlConnection("Server=DELL-PC; User Id=sa;Password=123;Database=comments");
con.Open();
SqlCommand cmd = new SqlCommand("insert into tbl_comments(comment, ipAddress, Date)values(@p1, @p2, @p4)", con);
cmd.Parameters.AddWithValue("@p1", Txtcomments.Text);
cmd.Parameters.AddWithValue("@p2", ipaddress);
date = DateTime.Now.ToString();
cmd.Parameters.AddWithValue("@p4", date);
int i = cmd.ExecuteNonQuery();
if (i > 0)
{
Label1.Text = "Your comment has been posted successfully";
Label4.Text = " " ;
}
con.Close();
}
}
this is my Throttler class
public class Throttler
{
private int _requestLimit;
private int _timeoutInSeconds;
private string _key;
public static string NextAccessDate;
public bool RequestShouldBeThrottled(string key, int requestLimit = 5, int timeoutInSeconds = 180)
{
_requestLimit = requestLimit;
_timeoutInSeconds = timeoutInSeconds;
_key = key;
ThrottleInfo throttleInfo = (ThrottleInfo)HttpRuntime.Cache[_key];
if (throttleInfo == null)
{
throttleInfo = new ThrottleInfo
{
ExpiresAt = DateTime.Now.AddSeconds(_timeoutInSeconds),
RequestCount = 0,
};
NextAccessDate=throttleInfo.ExpiresAt.ToString();
}
throttleInfo.RequestCount++;
HttpRuntime.Cache.Add(_key,
throttleInfo,
null,
throttleInfo.ExpiresAt,
Cache.NoSlidingExpiration,
CacheItemPriority.Normal,
null);
return (throttleInfo.RequestCount > _requestLimit);
}
}
this is my ThrottleInfo class
public class ThrottleInfo
{
public DateTime ExpiresAt { get; set; }
public int RequestCount { get; set; }
}
i changed my source code and tried to use cookies such that i could restrict the particular user upto some extent if he makes the request from that particular bowser(say Google) it is restricting but the problem is as we know that cookies are browser dependent the same person send requests from the other browser (say firefox) how ca i restrict the user to do so .
here is the source code what i had changed from the above
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
ipaddress = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
if (ipaddress == "" || ipaddress == null&&(Request.Cookies["Appcookie"]==null))
{
ipaddress = Request.ServerVariables["REMOTE_ADDR"];
strSessionID = HttpContext.Current.Session.SessionID;
HttpCookie httpCookie = new HttpCookie("Appcookie");
UID = GetUniqueID();
Response.Cookies["Appcookie"].Value = UID;
httpCookie.Expires = DateTime.Now.AddDays(1);
}
}
}
private static Random random = new Random();
private string GetUniqueID()
{
const string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
return new string(Enumerable.Repeat(chars,10)
.Select(s => s[random.Next(s.Length)]).ToArray());
}