有没有办法计算Web API中对post方法的调用次数?
例如:如果他3次输入错误的用户名和密码组合,我想禁用用户。 所以在连续第三次调用之后,我想做一些Web API控制器的post方法(比如我会以某种方式禁用用户)。
如何计算此调用API控制器方法?是否已为此案例定义了属性或方法?
更新:
这是我的Web API方法:
[Route("login")]
public async Task<HttpResponseMessage> LoginUser(Login model)
{
using (AuthRepository repo = new AuthRepository())
{
Regex rgx = new Regex("[^a-zA-Z0-9 -]");
string deviceId = rgx.Replace(model.DeviceId, "");
var request = HttpContext.Current.Request;
var user = await repo.FindUserAsync(deviceId, model.PIN);
var tokenServiceUrl = request.Url.GetLeftPart(UriPartial.Authority) + request.ApplicationPath + "/Token";
if (user != null)
{
MatrixLogManager.Debug("User " + model.DeviceId + "successfully logged in on MatrixSTS.");
try
{
using (var client = new HttpClient())
{
var requestParams = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("grant_type", "password"),
new KeyValuePair<string, string>("username", deviceId),
new KeyValuePair<string, string>("password", model.PIN)
};
var requestParamsFormUrlEncoded = new FormUrlEncodedContent(requestParams);
var tokenServiceResponse = await client.PostAsync(tokenServiceUrl, requestParamsFormUrlEncoded);
var responseString = await tokenServiceResponse.Content.ReadAsStringAsync();
var responseCode = tokenServiceResponse.StatusCode;
var responseMsg = new HttpResponseMessage(responseCode)
{
Content = new StringContent(responseString, Encoding.UTF8, "application/json")
};
return responseMsg;
}
}
catch (Exception ex)
{
MatrixLogManager.Error("Error: ", ex);
throw ex;
}
}
else
{
//IF LOGIN FAILD I WOULD NEED TO COUNT SOMEHOW THAT ONE CALL WAS UNSUCCESSFUL, AFTER THIRD I WILL BLOCK USER, BUT ONLY IT HE MAKES SAME MISTAKE 3 TIMES IN A ROW.
//Adding simple int counter didn't worked for me.
return Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid username or password.");
}
}
}
答案 0 :(得分:2)
你应该把这个东西保存在一个名为“让UserInvalidFailureLogins:
”的子表中的数据库中该表将具有userId的外键,并具有计数器值。
当用户尝试登录时,首先要检查用户有多少次失败 如果他超过了门槛,则不要让他登录,直到你重置尝试次数。
如果用户登录失败,则将计数器递增1。
答案 1 :(得分:1)
您可以实现此目的的一种简单方法是保留静态Dictionary<TKey, TValue>
,将用户映射到他们尝试登录的次数。请注意,根据用户数量以及您希望保持计数状态的时间,这可能会使内存膨胀很多:
private static readonly Dictionary<string, int> loginAttemptsByDeviceId =
new Dictionary<string, int>();
然后将其添加到您的else
子句中:
else
{
int loginAttempts;
if (loginAttemptsByDeviceId.TryGetValue(deviceId, out loginAttempts)
{
loginAttemptsByDeviceId[deviceId] = ++loginAttempts;
}
else
{
loginAttemptsByDeviceId.Add(deviceId, 1);
}
return Request.CreateErrorResponse(HttpStatusCode.Unauthorized, "Invalid username or password.");
}
当然,在记录用户之前检查值:
int currentUserAttempts;
if (loginAttemptsByDeviceId.TryGetValue(deviceId, out currentUserAttempts) &&
currentUserAttempts == MaxLoginThreshhold)
{
// Return some error to the user.
}
这假定DeviceID
是每个用户的唯一标识符。如果不是,请使用唯一标识您的用户的值。
注意我会建议你长期保持这个数据在某个地方(如果需要)。另请注意,这不会考虑可能尝试的并发请求。如果这是一个问题,请考虑使用ConcurrentDictionary<TKey, TValue>
代替锁定相关位置。