Задать вопрос
@Alano

Почему не проходит программная авторизация в vk.com через oauth, но без браузера?

Проблема в том, что после отправки запроса на непосредственно авторизацию (с куками и всем прочим), в ответ приходит страничка, на которой написано, что логин или пароль неверны. Хотя они верны. Пробовал даже две разных учетки на всякий случай.
Использовал этот образец. До этого пробовал писать что-то свое с таким же результатом.
public static void A()
        {
            var id = ...;
            var scope = "messages";
            var t = $"http://api.vkontakte.ru/oauth/authorize?client_id={id}&scope={scope}&display=wap&response_type=token";
            var myReq = (HttpWebRequest)HttpWebRequest.Create(t);
            var myResp = (HttpWebResponse)myReq.GetResponse();
            var myStream = new StreamReader(myResp.GetResponseStream(), Encoding.UTF8);
            var html = myStream.ReadToEnd();
            Regex myReg = new Regex("<form(.*?)>(?<form_body>.*?)</form>", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline);
            html = myReg.Match(html).Groups["form_body"].Value;
            myReg = new Regex("<input(.*?)name=\\\"(?<name>[^\\x22]+)\\\"(.*?)((value=\\\"(?<value>[^\\x22]*)\\\"(.*?))|(.?))>", RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline);
            NameValueCollection qs = new NameValueCollection();
            foreach (Match m in myReg.Matches(html))
            {
                string val = m.Groups["value"].Value;
                if (m.Groups["name"].Value == "email")
                {
                    val = ...
                }
                else if (m.Groups["name"].Value == "pass")
                {
                  
                    val = ...
                }
                qs.Add(m.Groups["name"].Value, HttpUtility.UrlEncode(val));
            }

            byte[] b = System.Text.Encoding.UTF8.GetBytes(string.Join("&", from item in qs.AllKeys select item + "=" + qs[item]));

            myReq = (HttpWebRequest)HttpWebRequest.Create("https://login.vk.com/?act=login&soft=1&utf8=1");
            myReq.CookieContainer = new CookieContainer();
            myReq.Method = "POST";
            myReq.ContentType = "application/x-www-form-urlencoded";
            myReq.ContentLength = b.Length;
            myReq.GetRequestStream().Write(b, 0, b.Length);
            myReq.AllowAutoRedirect = false;

            myResp = (HttpWebResponse)myReq.GetResponse();

            CookieContainer cc = new CookieContainer();
            foreach (Cookie c in myResp.Cookies)
            {
                cc.Add(c);
            }

            if (!String.IsNullOrEmpty(myResp.Headers["Location"]))
            {

                myReq = (HttpWebRequest)HttpWebRequest.Create(myResp.Headers["Location"]);
                myReq.CookieContainer = cc;// передаем куки
                myReq.Method = "GET";
                myReq.ContentType = "text/html";

                myResp = (HttpWebResponse)myReq.GetResponse();
                myStream = new StreamReader(myResp.GetResponseStream(), Encoding.UTF8);
                html = myStream.ReadToEnd();
            }

            myReg = new Regex("Вы авторизованы как <b><a href=\\\"(?<url>[^\\\\x22]+)\\\">(?<user>[^\\\\x3c]+)</a></b>",
                RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline);
            if (!myReg.IsMatch(html))
            {
                Console.WriteLine("авторизация не прошла");
                return;
            }

            Console.WriteLine($"Авторизация успешно прошла.\\nПользователь {myReg.Match(html).Groups["user"].Value}");

            myReg = new Regex("<form(.*?)action=\\\"(?<post_url>[^\\\\x22]+)\\\"(.*?)>(?<form_body>.*?)</form>",
                RegexOptions.IgnoreCase | RegexOptions.Multiline | RegexOptions.Singleline);
            if (!myReg.IsMatch(html))
            {
                Console.WriteLine("Не удалось получить форму. Проверьте шаблон регулярного выражения.");
                return;
            }

            string url = myReg.Match(html).Groups["post_url"].Value;
            if (!url.ToLower().StartsWith("http://")) { url = String.Format("http://api.vkontakte.ru{0}", url); }

            myReq = (HttpWebRequest)HttpWebRequest.Create(url);
            myReq.CookieContainer = cc; // не забываем передавать куки
            myReq.Method = "POST";
            myReq.ContentType = "application/x-www-form-urlencoded";
            myReq.AllowAutoRedirect = false;

            myResp = (HttpWebResponse)myReq.GetResponse();
            string accessToken;
            string userId;
            if (!String.IsNullOrEmpty(myResp.Headers["Location"]))
            {
                myReg = new Regex(@"(?<name>[\\w\\d\\x5f]+)=(?<value>[^\\x26\\s]+)", RegexOptions.IgnoreCase | RegexOptions.Singleline);
                foreach (Match m in myReg.Matches(myResp.Headers["Location"]))
                {
                    if (m.Groups["name"].Value == "access_token")
                    {
                        accessToken = m.Groups["value"].Value;
                    }
                    else if (m.Groups["name"].Value == "user_id")
                    {
                        userId = m.Groups["value"].Value;
                    }
                }
            }
            else
            {
                Console.WriteLine("Ошибка. Ожидался редирект.");

            }
        }
  • Вопрос задан
  • 1203 просмотра
Подписаться 1 Оценить Комментировать
Решения вопроса 1
@VanKrock
Если вы хотите авторизацию по логину и паролю, можете использовать https://vknet.github.io/vk/authorize/
Но у этого есть ряд проблем, например 2х факторная аутентификация не работает, как в принципе и в вашем коде.
Самое лучшее все таки использовать форму с браузером.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы