Pull to refresh

AlfabankAPI для работы с Альфа-Клиент On-line

Reading time3 min
Views23K
Как и у многих, в один прекрасный день появилась идея автоматизировать бизнес процессы в своей организации. Так или иначе автоматизировать можно всё и бесконечно долго, но задача по работе с банком показалась наиболее важной и интересной. Перед началом исследования стоит предъявить требования к необходимому API с помощью которого мы ходим общаться с банком. На первом этапе неплохо было бы установить соединение с банком, получить текущий баланс и список операций по счёту на указанный период.

Поиск готовых решений от банков мало что дал. У многих банков подобное API отсутствует в принципе.

Раз всё так плохо, создадим свой API с блэкджеком и для достижения цели. Так как автор работает с компанией Альфа-Банк, то и API будет на примере данного банка, но очень надеюсь, что после прочтения начнутся открытые разработки и для остальных.

Очевидно, что не имея специальных инструментов для работы с банками, общаться с ними придётся по протоколу https, а значит результат мы будем получать и обрабатывать в виде html. Для этого запаситесь соответствующими библиотеками.
Решение нашей проблемы сводится к двум основным задачам. Первая – это изучить как наш браузер общается с банком, и вторая – повторить увиденное в нашем API. У большинства программистов это не составит большого труда.

Анализ запросов


  1. При загрузке страницы ibank.alfabank.ru/ALFAIBS32 видим, что в ответе содержится jsessionid, который используется в следующем post-запросе.
  2. Второй запрос использует jsessionid, и передаёт команду на загрузку формы авторизации.
    Запрос:
    https://ibank.alfabank.ru/ALFAIBS32/ControllerServlet;jsessionid=...

    Команда: command&auth_loginByPasswordPage
  3. С возвратом формы авторизации, мы уже получаем OTOKey и новый id сессии, который отличается от первого, после чего система ожидает ввода логина и пароля.
  4. Последним шагом остаётся отправить данные авторизации с учётом нового jsessionid и проверить результат. Выглядит это примерно следующим образом:



    Если всё прошло успешно, то в ответе сервера мы найдём очередной jsessionid, но на этот раз он будет является последним, и использоваться во всех последующих запросах.
  5. Проверить успех авторизации можно попробовав найти в ответе тэг:

    <INPUT type='hidden' name='command' value='dashboard_preparePage'>
    

    По которому уже загружается главная страница кабинета.


Разработка


Дабы не докучать скучным кодом, остановимся только на построении запросов к серверу для авторизации. В примере не представлен способ получения необходимых данных из html ответов сервера. Стоит отметить, что при авторизации не используются cookies.
Пример построения запросов
private void SetRequestData(HttpWebRequest request, string data)
{
   var encoding = new ASCIIEncoding();
   byte[] byte1 = encoding.GetBytes(data);
   request.ContentLength = data.Length;
   var stream = request.GetRequestStream();
   stream.Write(byte1, 0, byte1.Length);
   stream.Close();
 }

public void Connect(string login, string password)
{
   // 1. Get- запрос для получения sessionId1
   var url = "https://ibank.alfabank.ru/ALFAIBS32/";
   var request = (HttpWebRequest)HttpWebRequest.Create(url);
   var response = (HttpWebResponse)request.GetResponse();

   // Получаем первый jsessionid из ответа
   // sessionId1 = …

   // 2. Post- запрос для получения формы авторизации с новым jsessionid
   var controller = url  +"ControllerServlet;jsessionid={0}";
   url =string.Format(controller, sessionId1);
   request = (HttpWebRequest)HttpWebRequest.Create, url);
   request.Method = "POST";
   request.ContentType = "application/x-www-form-urlencoded";
   SetRequestData(request, "command=auth_loginByPasswordPage");
   response = (HttpWebResponse)request.GetResponse();

   // Получаем из ответа otokey и новый jsessionid
   // var otokey = …
   // sessionId2 = …

   // 3. Заключительный запрос для завершения авторизации
   url =string.Format(controller, sessionId2);
   request = (HttpWebRequest)HttpWebRequest.Create, url);
   request.Method = "POST";
   request.ContentType = "application/x-www-form-urlencoded";

   var postData = string.Format(
        "command=auth_loginByPassword&username={0}&password{1} " +
        "&null_div_expanded=false&OTOKey={2}", login, password, otokey);

   SetRequestData(request, postData);
   response = (HttpWebResponse)request.GetResponse();

   // Profit!
}



Результат


Настало проверить результаты работы нашего небольшого API:
AlfabankAPI: Hello world!
class Program
{
   static void Main(string[] args)
   {
      var api = new AlfabankAPI.AlfabankAPI();
      api.Connect("k000000", "qwerty");

     Console.WriteLine("Balance: {0}", api.GetBalance());

     var date1 = new DateTime(2013, 9, 1);
     var date2 = DateTime.Now;
     var account = "40700000000000000000";

     var operations = api.GetMovementOnAccount(account , date1, date2);

     foreach (var o in operations)
        Console.WriteLine("{0} {1} {2}", o.Number, o.DateSend, o.Amount);

      Console.ReadKey();
   }
}





Заключение


Надеюсь эта статья вдохновит на создание более качественного и открытого API для различных банков.
Github: AlfabankAPI
Всем пятницы.
Tags:
Hubs:
+25
Comments22

Articles

Change theme settings