понедельник, 2 июля 2012 г.

C# Авторизация ВКонтакте через http без api

В этой статье вы увидите уже готовую функцию, которая авторизует клиента по логину и паролю и возвращает булево значение true или false в зависимости от того, прошла авторизация или нет.
В следующей статье будет рассмотрено то, как я пришёл к этому коду и как вообще делать авторизацию через http на других сайтах.

При работе будет использоваться библиотека HtmlAgilityPack для парсинга Html. Подробнее об этой библиотеке можно прочесть тут.

Авторизация проходит через мобильную версию сайта контакта, так как это проще в реализации.

Вот функция:
        public bool http_auth_vk(string login, string pass)
        {
            //*****************************
            //Получаем action_url
            //*****************************
            System.Net.ServicePointManager.ServerCertificateValidationCallback = delegate { return true; };
            System.Net.WebRequest reqGET = System.Net.WebRequest.Create("http://m.vk.com/");
            System.Net.WebResponse resp = reqGET.GetResponse();
            System.IO.Stream stream = resp.GetResponseStream();
            System.IO.StreamReader sr = new System.IO.StreamReader(stream);
            string s = sr.ReadToEnd();


            //*****************************
            //Парсим
            //*****************************
            HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
            doc.LoadHtml(s);
            HtmlNode bodyNode = doc.DocumentNode.SelectSingleNode("//div[@class='cont']/form");
            string result1 = bodyNode.Attributes["action"].Value;

            //*****************************
            //POST запрос
            //*****************************
            var cookies = new CookieContainer();
            ServicePointManager.Expect100Continue = false;
            var request = (HttpWebRequest)WebRequest.Create(result1);
            request.CookieContainer = cookies;
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            using (var requestStream = request.GetRequestStream())
            using (var writer = new StreamWriter(requestStream))
            {
                writer.Write("email=" + login + "&pass=" + pass);
            }

            using (var responseStream = request.GetResponse().GetResponseStream())
            using (var reader = new StreamReader(responseStream))
            {
                var result = reader.ReadToEnd();

                //*****************************
                //Парсим, поиск ID
                //*****************************                 
                HtmlAgilityPack.HtmlDocument doc2 = new HtmlAgilityPack.HtmlDocument();                
                doc2.LoadHtml(result);
                string result2;
                try
                {                                     
                    
                    HtmlNode bodyNode2 = doc2.DocumentNode.SelectSingleNode("//div[@class='user_wrap']/a");
                    result2 = bodyNode2.Attributes["href"].Value.Substring(3);
                    //Если ID найден, то авторизация удалась
                    return true;
                }
                catch
                {
                    //Если ID не найден, то авторизация не удалась
                    MessageBox.Show("Ошибка авторизации, проверьте правильность введённых данных.\nВозможно там капча.");
                    return false;
                }
            }
        }

Пример использования:

        private void button1_Click(object sender, EventArgs e)
        {
            string login = textBox1.Text;
            string pass = textBox2.Text;
            bool avt = http_auth_vk(login, pass);
            if (avt == true)
            {
                toolStripStatusLabel1.Text = "Авторизовались успешно";

            }
            else {
                toolStripStatusLabel1.Text = "Данные не верны, попробуйте снова";
            }
        }


Необходимо делать импорт библиотек как показано ниже:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Net;
using System.IO;
using HtmlAgilityPack;

В своей программе я использовал виджет статусной строки statusStrip и после проверки авторизации результат появлялся там.
Вот так выглядит мой вариант:
Вот исходники:
 VK Simple.rar   155 KB
Работа через Http без использования Api может быть нужна только лишь для проверки валидности аккаунта(ов), так как все остальные действия уже делать во много раз сложнее. Разработчики контакта пожизненно борются с ботами, которые работают через http и результат реально виден. Если вы хотите программным путём работать с группами, друзьями, пабликами и тд, то делать это будет логично только используя api.
Как работать с Api контакта рассказано в этой статье.

10 комментариев:

  1. >Работа через Http без использования Api может быть нужна только лишь для проверки валидности аккаунта(ов), так как все остальные действия уже делать во много раз сложнее

    Невсегда правда, т.к. некоторые действия, насколько я понял, невозможно делать через API. Например, поиск по типам сообществ, месту и прочее с помощью groups.search. В API есть лишь параметр q, который, судя по всему, не позволяет определять данные критерии

    ОтветитьУдалить
  2. Вячеслав здравствуйте. У меня к вам есть пару вопросов по шарпу, как с вами можно связатся? Идеальный вариант по скайпу если можно.
    Николай

    ОтветитьУдалить
  3. Этот комментарий был удален автором.

    ОтветитьУдалить
  4. а как после авторизации получить исходный код другой страницы?

    ОтветитьУдалить
  5. При нажатии кнопки ошибка "Ссылка на объект не указывает на экземпляр объекта." строка
    string result1 = bodyNode.Attributes["action"].Value;

    Как исправить?
    Моя почта Delphicpp@yandex.ru

    ОтветитьУдалить
  6. Автор же все объясняет. Где, что и откуда.
    Название слассов изменили, замени 2 аргумента, лентяй:
    для bodyNode - "//div[@class='form_item fi_fat']/form"
    для bodyNode2 - "//div[@class='ip_user_link']/a"

    ОтветитьУдалить
  7. Еще мельче шрифт кода нельзя сделать?

    ОтветитьУдалить
  8. Необработанное исключение типа "System.NullReferenceException" в VK Simple.exe
    Дополнительные сведения: Ссылка на объект не указывает на экземпляр объекта.

    Как исправить?

    ОтветитьУдалить
  9. HtmlNode bodyNode = doc.DocumentNode.SelectSingleNode("//div[@class='form_item fi_fat']/form");
    но сдаётся мне, что код уже не рабочий ;)

    ОтветитьУдалить
  10. Да как раз токи рабочий, спасибо огроменное, но есть проблема в другом строка для передачи POST запроса изменилась. Как победить не знаю

    ОтветитьУдалить