2015-04-16 2 views
2

Есть ли способ подсчитать количество вызовов метода post в Web API?Как подсчитать вызовы метода POST Web API POST

Например: Я хочу отключить пользователя, если он 3 раза вводит неправильную комбинацию имени пользователя и пароля. Итак, после третьего вызова в строке метода post контроллера Web API я хочу что-то сделать (например, я как-нибудь отключу пользователя).

Как считать этот вызов методом API-контроллера? Есть ли уже определенное свойство или метод для этого случая?

UPDATE:

Это мой метод 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

Вы что-то пробовали? –

+0

@YuvalItzchakov Я пытался использовать простой счетчик int, но не успел ... Он учитывает это только в первый раз, после того, как следующее значение вызова останется таким же ... –

+0

Не могли бы вы показать нам свой код? –

ответ

2

Вы должны сохранить этот материал в БД в подкаталоге таблицу с именем, скажем, UserInvalidFailureLogins:

таблица будет иметь внешний ключ к USERID и будет иметь значение счетчика.

Когда пользователь пытается войти в систему, сначала проверьте, сколько ошибок у пользователей и , если он превысил порог, а затем не позволяйте ему входить в систему до тех пор, пока вы не сбросите количество попыток.

Если пользователь не выполнил вход в систему, вы увеличиваете счетчик на 1.

+1

Hvala Amire :) Мне нравится этот подход, и я тоже попробую его, потому что мне все равно нужно сохранить это значение в базе данных. @amirpopovich –

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> и блокировки в соответствующих местах.

+1

спасибо за ответ, я попробую прямо сейчас ... Моя цель - сохранить это значение где-то в базе данных, потому что возможно, что ему нужно будет проверить его в некоторых других вызовах :) @yuvalitzchakov –

+1

@ nemo_87 Затем создайте таблицу сопоставление пользователей с их попытками и запрос, прежде чем пытаться войти в систему пользователя. Это будет более подходящий долгосрочный подход. –