Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Megaplan API


Автор: infarch 5.12.2014, 11:22
Приходилось ли кому нибудь работать с api мегаплана? Я уже второй день бьюсь над ним, пока получилось только залогиниться. Запросы данных не проходят, получаю сообщение "unauthorized". Использую RestSharp. Вот мой код:

Код

    class Api
    {
        const string Host = "mydomain.megaplan.ru";
        const string BaseUrl = "http://" + Host;
        const string ContentType = "application/x-www-form-urlencoded";

        private Login Login { get; set; }

        public Api(string username, string password)
        {
            Login = GetLogin(username, GetMd5Hash(password));
        }

        private static string BytesToHex(byte[] data)
        {
            StringBuilder sBuilder = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }
            return sBuilder.ToString();
        }

        static string GetMd5Hash(string input)
        {
            using (MD5 md5Hash = MD5.Create())
            {
                byte[] data = md5Hash.ComputeHash(Encoding.UTF8.GetBytes(input));
                return BytesToHex(data);
            }
        }

        public T Execute<T>(RestRequest request) where T : new()
        {
            var client = new RestClient(BaseUrl);
            var response = client.Execute<T>(request);
            if (response.ErrorException != null)
            {
                const string message = "Error retrieving response.  Check inner details for more info.";
                var exception = new ApplicationException(message, response.ErrorException);
                throw exception;
            }
            return response.Data;
        }

        private Login GetLogin(string login, string passwordMd5)
        {
            var request = new RestRequest();
            request.Resource = "/BumsCommonApiV01/User/authorize.api";
            request.RootElement = "data";
            request.AddParameter("Login", login);
            request.AddParameter("Password", passwordMd5);
            return Execute<Login>(request);
        }

        private string GetXAuthHeader(string signature, string accessId, string secretKey)
        {
            var cryptoProvider = new HMACSHA1(Encoding.UTF8.GetBytes(secretKey));
            byte[] encriptedBytes = cryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(signature));
            string encryptedString = encriptedBytes.Aggregate("", (s, e) => s + String.Format("{0:x2}", e), s => s);
            return accessId + ":" + Convert.ToBase64String(Encoding.UTF8.GetBytes(encryptedString));
        }
        
        private void SignRequest(RestRequest request)
        {
            DateTime requestDate = DateTime.UtcNow;
            string requestDateRfc = requestDate.ToString("r", CultureInfo.InvariantCulture);
            string signhost = Host + request.Resource;
            string signature = string.Join("\n",
                new string [] { request.Method.ToString(), "", ContentType, requestDateRfc, signhost });
            
            string xAutHeader = GetXAuthHeader(signature, Login.AccessId, Login.SecretKey);

            request.AddHeader("Accept-Encoding", "identity");
            request.AddHeader("Accept", "application/json");
            request.AddHeader("User-Agent", "SdfApi_Request");
            request.AddHeader("Date", requestDateRfc);
            request.AddHeader("X-Authorization", xAutHeader);
        }

        public Client FindClient(string phone)
        {
            var request = new RestRequest();
            request.Resource = "/BumsCrmApiV01/Contractor/list.api";
            request.Method = Method.GET;
            request.RootElement = "data";
            request.AddParameter("FilterId", "all");
            request.AddParameter("Limit", "1");
            request.AddParameter("Phone", "223322");

            SignRequest(request);

            return Execute<Client>(request);
        }

    }



Авторизация работает, а метод FindClient - нет. Вроде все сделал как положено. Кто подскажет в чем дело?

Автор: Экскалупатор 5.12.2014, 20:37
Сталкивался в некоторых сервисах. При авторизации выдается ключ, который потом нужно использовать в каждом запросе. Иначе получаем ошибку авторизации. Возможно тут так же.

Этот ответ добавлен с нового Винграда - http://ru.vingrad.com/Megaplan-API-id54816ba4ae20157e318b4567#findElement_E7045_5481ed4fae2015091f13071a_0

Автор: infarch 8.12.2014, 17:49
Цитата(Экскалупатор @  5.12.2014,  20:37 Найти цитируемый пост)
При авторизации выдается ключ, который потом нужно использовать в каждом запросе


Да, это понятно... Но я и залогинился, и ключи получил. А вот с подписями неувязка, что то не то. Копаю дальше...

Автор: Ivankult 23.9.2016, 02:43
Добрый вечер. Прошу прощения за оффтоп, но...
Вам удалось решить проблему? Ибо четвертый день долблю эту тему, насилую мозг техподдержке, но на все пподписанные запросы приходит 401. Сигнатура считается верно, ТП подтвердило. Но ТП расписалось в своем бессилии и предложило переписать все на ПХП, т.к. "на ПХП все работает". Чудики.
Может, там есть какая хитрость?

Автор: infarch 23.9.2016, 10:10
Помню, а как же ) Вот тут посмотрите: https://help.megaplan.ru/API_authentication . Тогда еще была старая версия документации, и параметр Content-MD5 никак небыл отмечен особо. Ну я его и передавал. А оказалось что его не нужно. Забрал, все заработало. Хотя у вас может быть и иная проблема, они же там затейники.

Добавлено через 8 минут и 59 секунд
Ну и насчет php тоже верно, там кое что имеет свою специфику. Вот вам пару классов из того проекта, поглядите.

Автор: Ivankult 23.9.2016, 16:54
Уиии! Спасибо.. сча глянем!

Автор: Ivankult 23.9.2016, 17:11
Добрый день. По их докам и работал, но там все тухло. Отправлял посредством HttWebRequest, а с рестшарпом так и не разобрался. Ковырял ваши исходники - классно написано, но как и прочие примеры рестшарпа - валит ошибками:

Код


Не удалось найти имя типа или пространства имен "Login" (пропущена директива using или ссылка на сборку?)    

Comagic2Megaplan.Megaplan.Api.Login" является "свойство", но используется как "тип"    

Не удалось найти имя типа или пространства имен "Client" (пропущена директива using или ссылка на сборку?)    

Не удалось найти имя типа или пространства имен "Deal" (пропущена директива using или ссылка на сборку?)    


NuGet пакет рестшарпа подключен, что ему еще может быть надо?

Добавлено через 3 минуты и 15 секунд
Илии же Login, Client и Deal - ваши классы, которые в том же namesace, но другом файле, обертки ответов на запросы для десериализации ответов в объект класса?

Добавлено через 8 минут и 21 секунду
И что тогда такое ResponseWrapper? Тоже кастомный класс - парсер - преобразователь строки в экземплр заданного класса?
Можно попросить исодники всех вышеперечисленных классов, ежели это не будет излишней наглостью? Рестшарп оказался для меня слишком странным.

Автор: infarch 26.9.2016, 10:43
Врапер, как  Login, Client и Deal - это сущности которые заполняются рестшарпом согласно полученного json. Почитайте рестшарповские доки, там все это есть. Весь солюшен я вам дать не могу, там определенные ограничения. Вот прикладываю неймспейс мегаплана, его должно хватить для понимания.

Автор: Ivankult 26.9.2016, 20:24
Спасибо! Буду анализировать! 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)