Страва вход через httpwebrequest не удалось - PullRequest
0 голосов
/ 17 декабря 2018

Привет, я пытаюсь войти через https://www.strava.com/session с помощью HttpWebrequest, но он не регистрирует меня. Он дает ответ 302, что хорошо, но никогда не перенаправляет меня на https://www.strava.com/dashboard.

это код, который я использую

Httpclient:

public class HttpClient
{

    private const string UserAgent = "Mozilla/5.0";

    public CookieCollection CookieCollection;

    public HttpWebRequest WebRequest;
    public HttpWebResponse WebResponse;
    public int code { get; set; }
    public string location { get; set; }


    public string PostData(string url, string postData, string refer = "")
    {

        WebRequest = (HttpWebRequest)System.Net.WebRequest.Create(url);
        WebRequest.UserAgent = UserAgent;
        WebRequest.Referer = refer;

        WebRequest.AllowAutoRedirect =false;
        WebRequest.Timeout = 10000;
        WebRequest.KeepAlive = true;
        WebRequest.CookieContainer = new CookieContainer();

        if (CookieCollection != null && CookieCollection.Count > 0)
        {
            WebRequest.CookieContainer.Add(CookieCollection);

        }


        WebRequest.ContentType = "application/x-www-form-urlencoded; charset=UTF-8";
        WebRequest.Method = "POST";

        try
        {
            var postBytes = Encoding.UTF8.GetBytes(postData);
            WebRequest.ContentLength = postBytes.Length;
            var postDataStream = WebRequest.GetRequestStream();
            postDataStream.Write(postBytes, 0, postBytes.Length);
            postDataStream.Close();
            try
            {
                WebResponse = (HttpWebResponse)WebRequest.GetResponse();

                this.code = (int)WebResponse.StatusCode;
                this.location = WebResponse.Headers["Location"];
                if (WebResponse.StatusCode == HttpStatusCode.OK ||WebResponse.StatusCode == HttpStatusCode.Redirect)
                {


                    WebResponse.Cookies = WebRequest.CookieContainer.GetCookies(WebRequest.RequestUri);

                    if (WebResponse.Cookies.Count > 0)
                    {

                        if (CookieCollection == null)
                        {
                            CookieCollection = WebResponse.Cookies;
                        }
                        else
                        {
                            foreach (Cookie oRespCookie in WebResponse.Cookies)
                            {
                                var bMatch = false;
                                foreach (
                                    var oReqCookie in
                                        CookieCollection.Cast<Cookie>()
                                            .Where(oReqCookie => oReqCookie.Name == oRespCookie.Name))
                                {
                                    oReqCookie.Value = oRespCookie.Value;
                                    bMatch = true;
                                    break;
                                }
                                if (!bMatch)
                                    CookieCollection.Add(oRespCookie);
                            }
                        }
                    }

                    var reader = new StreamReader(WebResponse.GetResponseStream());
                    var responseString = reader.ReadToEnd();
                    reader.Close();
                    return responseString;
                }
            }
            catch (WebException wex)
            {
                if (wex.Response != null)
                {
                    using (var errorResponse = (HttpWebResponse)wex.Response)
                    {
                        using (var reader = new StreamReader(errorResponse.GetResponseStream()))
                        {
                            var error = reader.ReadToEnd();
                            return error;
                        }
                    }
                }
            }
        }

        catch (Exception ex)
        {

            Console.WriteLine(ex.Message);
        }
        return "Error in posting data" ;
    }


    public string GetData(string url, string post = "")
    {

        var responseStr = string.Empty;
        WebRequest = (HttpWebRequest)System.Net.WebRequest.Create(url);
        WebRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8";
        WebRequest.Method = "GET";

        WebRequest.KeepAlive = true;
        WebRequest.Credentials = CredentialCache.DefaultCredentials;
        WebRequest.UserAgent = UserAgent;

        WebRequest.CookieContainer = new CookieContainer();
        if (CookieCollection != null && CookieCollection.Count > 0)
        {
            WebRequest.CookieContainer.Add(CookieCollection);
        }

        if (!string.IsNullOrEmpty(post))
        {
            var postBytes = Encoding.UTF8.GetBytes(post);
            WebRequest.ContentLength = postBytes.Length;
            var postDataStream = WebRequest.GetRequestStream();
            postDataStream.Write(postBytes, 0, postBytes.Length);
            postDataStream.Close();
        }


        WebResponse wresp = null;

        try
        {
            wresp = WebRequest.GetResponse();
            var downStream = wresp.GetResponseStream();
            if (downStream != null)
            {
                using (var downReader = new StreamReader(downStream))
                {
                    responseStr = downReader.ReadToEnd();
                }
            }
            return responseStr;
        }
        catch (Exception ex)
        {
            Console.WriteLine(ex.Message);
            if (wresp != null)
            {
                wresp.Close();
                wresp = null;
            }
        }
        finally
        {
            WebRequest = null;
        }
        return responseStr;
    }

}

Получение crfs-токена:

private string GetToken()
    {
        string token = "";
        String sourcestring = hc.GetData(loginURL);
        Regex metaTag = new Regex(@"<meta[\s]+[^>]*?name[\s]?=[\s""']+(.*?)[\s""']+content[\s]?=[\s""']+(.*?)[""']+.*?>");
        foreach (Match m in metaTag.Matches(sourcestring))
        {
            if (m.Groups[2].Value.Contains("token"))
            {
                continue;
            }

            token = m.Groups[2].Value;
        }

            return token;
    }

Настраиваемая пара ключей

private string PostParam(Dictionary<string, string> data)
    {
        var sb = new StringBuilder();
        var p = new List<string>();
        foreach (KeyValuePair<string, string> pair in data)
        {
            sb.Clear();
            sb.Append(pair.Key).Append("=").Append(pair.Value);
            p.Add(sb.ToString());
        }
        var pp = string.Join("&", p);
        return pp;
    }

Логин:

 private HttpClient hc = new HttpClient();

Данные словаря = новый словарь ();

        data.Add("utf8", "✓");
        data.Add("authenticity_token", GetToken());
        data.Add("plan", "");
        data.Add("email", "email");
        data.Add("password", "password");
        hc.PostData(sessionURL,WebUtility.UrlEncode(PostParam(data)), loginURL);

Может кто-нибудь сказать мне, что я делаю неправильно?если я смотрю заголовок запроса при попытке войти в браузер strava в браузере, то же самое, но все равно он не регистрирует меня.

Ответы [ 2 ]

0 голосов
/ 14 апреля 2019

примечание: вы можете использовать этот код (см. Мой предыдущий пост), чтобы изменить статус активности (конфиденциальность) после входа в систему:

Dictionary<string, string> data2 = new Dictionary<string, string>();
data2.Add("utf8", WebUtility.UrlEncode("✓"));
string token2 = GetToken();
string tokenEncoded2 = WebUtility.UrlEncode(token2);
data2.Add("_method", "patch");
data2.Add("authenticity_token", tokenEncoded2);
data2.Add("activity%5Bvisibility%5D", "only_me"); // or "followers_only"
string parameters2 = PostParam(data2);
hc.PostData("https://www.strava.com/activities/youractivityID", parameters2, loginURL);
0 голосов
/ 14 апреля 2019

Я нашел проблему.Вам нужно кодировать только токен (и символ UTF8), а не полные данные поста.

Это работает для меня (по какой-то причине мне нужно выполнить код два раза)

// First time says "logged out"
Dictionary<string, string> data = new Dictionary<string, string>();
data.Add("utf8", WebUtility.UrlEncode("✓"));
string token = GetToken();
string tokenEncoded = WebUtility.UrlEncode(token);
data.Add("authenticity_token", tokenEncoded);
data.Add("plan", "");
data.Add("email", "youremail");
data.Add("password", "yourpwd");
data.Add("remember_me", "on");
string parameters = PostParam(data);
hc.PostData(sessionURL, parameters, loginURL);

// Second time logs in
Dictionary<string, string> data = new Dictionary<string, string>();
data.Add("utf8", WebUtility.UrlEncode("✓"));
string token = GetToken();
string tokenEncoded = WebUtility.UrlEncode(token);
data.Add("authenticity_token", tokenEncoded);
data.Add("plan", "");
data.Add("email", "youremail");
data.Add("password", "yourpwd");
data.Add("remember_me", "on");
string parameters = PostParam(data);
hc.PostData(sessionURL, parameters, loginURL);

Примечание:

// Keep this on default value "true"
//WebRequest.AllowAutoRedirect = false;
...