Right off the bat - please do not suggest I use the Yahoo API. I am doing this purely as a learning experience and using the API would defeat the purpose.
I am using Fiddler to look at the HTTP traffic when I log into Yahoo mail (mail.yahoo.com) or Flickr. I see that the browser posts data to https://login.yahoo.com/config/login. Sample post data is:
.tries=1&.src=flickrsignin&.md5=&.hash=&.js=&.last=&promo=&.intl=us&.lang=en-US&.bypass=&.partner=&.u=811cdp17imj21&.v=0&.challenge=iwQ4dJLk0KhUP8Xlpyji_8ftQ.fe&.yplus=&.emailCode=&pkg=&stepid=&.ev=&hasMsgr=1&.chkP=Y&.done=https%3A%2F%2Flogin.yahoo.com%2Fconfig%2Fvalidate%3F.src%3Dflickrsignin%26.pc%3D8190%26.scrumb%3D0%26.pd%3Dc%253DJvVF95K62e6PzdPu7MBv2V8-%26.intl%3Dus%26.done%3Dhttp%253A%252F%252Fwww.flickr.com%252Fsignin%252Fyahoo%252F%253Fredir%253D%25252Fphotos%25252Ffriends%25252F&.pd=flickrsignin_ver%3D0%26c%3DJvVF95K62e6PzdPu7MBv2V8-%26ivt%3D%26sg%3D&.ws=1&.cp=0&pad=15&aad=15&popup=1&login=nkisnksd&passwd=noasno&.save=&passwd_raw=
As you see, there are lots of values in there, such as the challenge string, which I don't know how the browser comes up with it. How can I figure out the steps the browser is taking to come up with the challenge response? I assume it's an algorithm using the cookies stored when I GET the page, but just not sure how the browser automatically knows the algorithm?
Thanks!
Here is one approach that I used successfully. Essentially, you use the C# WebBrowser control and navigate to the login url. Then you loop through elements to find the login and password fields (you'll need to look at the page source to find out their names). Then you simulate the click on the login button.
void browser_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
//loaded the Yahoo login page
if (browser.Url.AbsoluteUri.Contains(loginUrl))
{
if (browser.Document != null)
{
//Find and fill the "username" textbox
HtmlElementCollection collection = browser.Document.GetElementsByTagName("input");
foreach (HtmlElement element in collection)
{
string name = element.GetAttribute("id");
if (name == "username")
{
element.SetAttribute("value", _login);
break;
}
}
//Find and fill the "password" field
foreach (HtmlElement element in collection)
{
string name = element.GetAttribute("id");
if (name == "passwd")
{
element.SetAttribute("value", _password);
break;
}
}
//Submit the form
collection = browser.Document.GetElementsByTagName("button");
foreach (HtmlElement element in collection)
{
string name = element.GetAttribute("id");
if (name == ".save")
{
element.InvokeMember("click");
break;
}
}
}
}
}
Here is another approach that also worked. I'm on the roll!
CookieContainer _yahooContainer;
string _login = "myyahoologin";
string _password = "myyahoopassword";
string strPostData = String.Format("login={0}&passwd={1}", _login, _password);
// Setup the http request.
HttpWebRequest wrWebRequest = WebRequest.Create(LoginUrl) as HttpWebRequest;
wrWebRequest.Method = "POST";
wrWebRequest.ContentLength = strPostData.Length;
wrWebRequest.ContentType = "application/x-www-form-urlencoded";
_yahooContainer = new CookieContainer();
wrWebRequest.CookieContainer = _yahooContainer;
// Post to the login form.
using (StreamWriter swRequestWriter = new StreamWriter(wrWebRequest.GetRequestStream()))
{
swRequestWriter.Write(strPostData);
swRequestWriter.Close();
}
// Get the response.
HttpWebResponse hwrWebResponse = (HttpWebResponse)wrWebRequest.GetResponse();
if (hwrWebResponse.ResponseUri.AbsoluteUri.Contains("my.yahoo.com"))
{
// you authenticated properly
}
// Now use the cookies to create more requests.
HttpWebRequest req = (HttpWebRequest)WebRequest.Create(_downloadUrl);
req.CookieContainer = _yahooContainer;
HttpWebResponse resp = (HttpWebResponse)req.GetResponse();