如何计算对ASP.NET Web API POST方法的调用

时间:2015-04-16 07:38:35

标签: c# asp.net asp.net-web-api

有没有办法计算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.");
            }
        }
    }

2 个答案:

答案 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>代替锁定相关位置。