VK oAuth2 Powershell VS C#

262
16 марта 2017, 19:23

Доброго времени суток!

Есть скрипт написанный на Powershell мной пару лет назад. Решил несколько его оптимизировать и перевести на c#, однако столкнулся с тем, что не проходит авторизация программно. Грешу на различную кодировку, но уже побайтово проверил, вроде все нормально, однако на powershell скрипт прекрасно выполняет авторизацию, и выполняется успешно, а на c# выкидывает на форму авторизации с ошибкой "неверный логин или пароль".

На powershell скрипт выглядит так:

$queryLogin = "https://oauth.vk.com/authorize?client_id=********&scope=groups,wall,photos&redirect_uri=https://oauth.vk.com/blank.html&display=wap&v=5.52&response_type=token";
$queryAPI = "https://api.vk.com/method/{0}.xml?{1}&v=5.52&access_token={2}";
$Cookie = new-object Net.CookieContainer;
$wReq = [Net.HttpWebRequest]::Create($queryLogin);
$wReq.CookieContainer = $Cookie;
$action = "";
$wResp = $wReq.GetResponse();
$stream = New-Object IO.StreamReader($wResp.GetResponseStream())
$str = $stream.ReadToEnd()
$stream.Close();
$wResp.Close();
$htmlDoc = New-Object HtmlAgilityPack.HtmlDocument;
$htmlDoc.LoadHtml($str);
$bodyNode = $htmlDoc.DocumentNode.SelectSingleNode("//form[@method='post'][@action]");
$action = $bodyNode.Attributes["action"].Value;
echo ("Action:`t" + $action)
$authparams = New-Object Collections.Hashtable
$htmlDoc.DocumentNode.SelectNodes("//input") |
%{
    $name = $_.Attributes["name"].value
    if ($name -ne $null)
    {
        $value = $_.Attributes["value"].value
        $authparams.Add($name, $value)
    }
}
$authparams["pass"] = $password
$authparams["email"] = $login
$str = ""
$authparams.Keys |
%{
    $str += ("&{0}={1}" -f $_, $authparams[$_])
}
$authData = [System.Text.Encoding]::UTF8.GetBytes($str.Trim("&"))
$wReq = [Net.HttpWebRequest]::Create($Action);
$wReq.CookieContainer = $Cookie;
$wReq.Method = "POST";
$wReq.ContentType = "application/x-www-form-urlencoded";
$wReq.ContentLength = $authData.Length
$writer = New-Object IO.StreamWriter($wReq.GetRequestStream());
$writer.Write($authData, 0, $authData.Length);
$writer.Close();
$wReq.AllowAutoRedirect = $false
$response = $wReq.GetResponse();
$headerLocation = $response.Headers["Location"]
$response.Close();

В $headerLocation имеем корректные данные.

На C# код выглядит так:

            var webRequest = (HttpWebRequest)WebRequest.Create(Properties.Resources.OAuth2);
            var Data = "";
            #region Загружаем страницу авторизации
            using (var webResponse = webRequest.GetResponse())
            {
                if (webResponse == null)
                {
                    throw new Exception("Не получен Response");
                }
                using (var stream = new StreamReader(webResponse.GetResponseStream()))
                {
                    Data = stream.ReadToEnd();
                    stream.Close();
                }
                if (string.IsNullOrEmpty(Data))
                {
                    throw new Exception("Возвращен пустой ответ");
                }
                webResponse.Close();
            }
            #endregion
            #region Парсим данные на странице, заполняем логин и пароль
            var htmlDoc = new HtmlAgilityPack.HtmlDocument();
            htmlDoc.LoadHtml(Data);
            var bodyName = htmlDoc.DocumentNode.SelectSingleNode(@"//form");
            if (bodyName == null)
            {
                throw new Exception("Не удалось получить форму с Action");
            }
            var action = bodyName.Attributes["action"].Value;
            if (string.IsNullOrEmpty(action))
            {
                throw new Exception("Полученный action пустой");
            }
            var authParams = new Dictionary<string, string>();
            foreach (var inputnode in htmlDoc.DocumentNode.SelectNodes("//input[@name][@value]"))
            {
                var name = inputnode.Attributes["name"].Value;
                var value = inputnode.Attributes["value"].Value;
                //authParams.Add(name, HttpUtility.UrlEncode(value));
                authParams.Add(name, value);
            }
            authParams["email"] = Properties.Resources.Email;
            authParams["pass"] = Properties.Resources.Password;
            var authParam = string.Join("&", from item in authParams
                                             select item.Key + "=" + item.Value);
            var authData = Encoding.Convert(Encoding.Unicode, Encoding.UTF8, Encoding.Unicode.GetBytes(authParam));
            #endregion
            #region Отправляем Логин и пароль
            webRequest = (HttpWebRequest)WebRequest.Create(action);
            webRequest.CookieContainer = Cookie;
            webRequest.Method = "POST";
            webRequest.ContentType = "application/x-www-form-urlencoded";
            webRequest.ContentLength = authData.Length;
            var writer = new StreamWriter(webRequest.GetRequestStream());
            //writer.Write(authData, 0, authData.Length);
            writer.Write(Encoding.UTF8.GetChars(authData, 0, authData.Length));
            writer.Close();
            webRequest.AllowAutoRedirect = false;
            var headerLocation = "";
            using (var response = webRequest.GetResponse())
            {
                headerLocation = response.Headers["Location"];
                response.Close();
            }
            if (string.IsNullOrEmpty(headerLocation))
            {
                throw new Exception("Не получен Location из заголовка");
            }
            #endregion

headerLocation отправил обратно на форму авторизации с ошибкой логина и пароля.

2-й день бьюсь, побороть не могу данную ошибку. Чую что провал в каких-то тонкостях отправки данных, но идти к wireshark очень не хочется...

Спасибо, если подскажите. Про VKApi на github знаю, он использует browser для тех же действий. Хотелось бы более лаконично пройти форму авторизации.

READ ALSO
Discord.Net opcode 9 Erorr

Discord.Net opcode 9 Erorr

Доброго времени суток

380
C# Chart видимое построение

C# Chart видимое построение

Как сделать что бы было видно как в chart строится график?

414
Как улучшить производительность mysql?

Как улучшить производительность mysql?

Имеется виртуальная машина, на ней 4 ядра 10г оперативной памяти, ssd диски в рейд 1Присутствует сайт: nginx + php + форк mysql(mariadb)

584
Проблема с авторизацией через guzzle

Проблема с авторизацией через guzzle

Все привет! Пытаюсь сделать авторизацию через guzzle для olx, но почему-ту в результате объекта $response, нужных кук - нетСамое странное что в логах...

517