Hi I'm trying to login via https://www.strava.com/session with HttpWebrequest but it doesn't log me in. It gives me an response of 302 which is good but it never redirect me to https://www.strava.com/dashboard.
this is the code that I'm using
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;
}
}
Getting crfs-token:
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;
}
Custom keyvaluepair
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;
}
Login:
private HttpClient hc = new HttpClient();
Dictionary data = new Dictionary();
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);
Can someone tell me what I'm doing wrong? if I look the request header when trying to login to strava in browser its the same but still it doesn't log me.
I found the problem. You need to encode only the token (and the UTF8 character), not the full post data.
This works for me (for some reason I need to run the code two times)
// 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);
Note:
// Keep this on default value "true"
//WebRequest.AllowAutoRedirect = false;