Jump to content

Authentication & Cookie handling - WP7 (Silverlight/C#)


travy92

Recommended Posts

Hey guys, I'm having problems authentication and getting a cookie to add to my requests to the WebUI API, specifically getting the list of torrents.

Here is my code:

public partial class MainPage : PhoneApplicationPage
{
public WebClient client = new WebClient();

public MainPage()
{
InitializeComponent();

//encode username:password
string authInfo = "you:wish"; //hidden
byte[] toEncodeAsBytes = System.Text.Encoding.UTF8.GetBytes(authInfo);
string returnValue = System.Convert.ToBase64String(toEncodeAsBytes);
client.Headers["Authorization"] = "Basic " + returnValue;

String torrentList = "http://localhost:50001/gui/token.html";
Uri torrents = new Uri(torrentList);

//handlers
client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);
client.OpenReadCompleted += new OpenReadCompletedEventHandler(client_ReadCompleted);

//get token
client.DownloadStringAsync(torrents);

}

private void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)
{
if (e.Error != null)
{
return;
}

//XML/Linq/JSON conversion
XElement xml = XElement.Parse(e.Result);

//testing purposes only
listBox1.ItemsSource = from value in xml.DescendantsAndSelf("html")
select new Token
{
token = value.Element("div").Value
};
listBox1.SelectedIndex = 0;
Token selected = listBox1.SelectedItem as Token;

//add token to request
Uri torrents = new Uri("http://localhost:50001/gui/?list=1&token=" + selected.token.ToString() + "");
client.OpenReadAsync(torrents);
}

public class Token
{
public string token { get; set; }
}

private void client_ReadCompleted(object sender, OpenReadCompletedEventArgs e)
{
try
{
//show results (should be list of torrents etc)

//open stream to the list of torrents in JSON form
Stream list = (Stream)e.Result;

list.Position = 0;
StreamReader read = new StreamReader(list);
String content = read.ReadToEnd();

var ser = new DataContractJsonSerializer(typeof(webAPIJSON));
webAPIJSON obj = ser.ReadObject(list) as webAPIJSON; //deserialze stream

MessageBox.Show(obj.NAME.ToString()); //show NAME element from JSON

read.Close();
}
catch (WebException exp)
{
//just a few tests to check the error message
MessageBox.Show("data: " + exp.Data);
MessageBox.Show("message: " + exp.Message);
HttpWebResponse response = exp.Response as HttpWebResponse;
MessageBox.Show("response: " + response.StatusDescription); //says ERROR, no other description
MessageBox.Show("status: " + exp.Status); //unknown
}
}

}

Basically, I make a new WebClient, add the header "Authorization: Basic <user:pass encoded into base64>" to my token request, retrieve the token and use the token in my next request to get the list of torrents.

However, it gives me an error upon trying (when trying to parse e.Result into a Stream). I believe it is because I am not attaching a cookie to the second request, but I have no idea how to with WebClient.

If anyone knows the solution, it would be very helpful!

Thanks.

Link to comment
Share on other sites

Unfortunately you can't add cookies to the stock standard Webclient in WP7. You can override the Webclient class to create one.

However, I personally use RestSharp for Windows Phone to do all my calls.

In my token request I use


var ResponseKeys = response.Headers["Set-Cookie"];
if (ResponseKeys != null)
{
var SplitItem = ResponseKeys.Split(';');
SettingsStore.CookieGUID = SplitItem[0];
}

to grab what I need (I also grab the token, but haven't included the code here), then use this to grab the torrent list.

 
string DownloadURI = string.Format("{0}:{1}/gui", SettingsStore.SelectedServer.Address, SettingsStore.SelectedServer.Port);
var client = new RestClient(DownloadURI);
client.Authenticator = new HttpBasicAuthenticator(SettingsStore.SelectedServer.Username, SettingsStore.SelectedServer.Password);
client.AddDefaultHeader("Cookie", SettingsStore.CookieGUID);
string RequestString = string.Format("?list=1&token={0}", SettingsStore.Token);
var request = new RestRequest(RequestString, Method.POST);
client.ExecuteAsync(request, (response) =>
{
if (response.ResponseStatus != ResponseStatus.Error && response.StatusCode == HttpStatusCode.OK)
{
// Do your stuff here
}
}

Link to comment
Share on other sites

Thanks dgaust.

I figured that if I can add an authorization header to the WebClient, I could possibly add a cookie header, and so using:

 client.Headers["Cookie"] = <cookie_value>

I was able to add the header (albeit artificially). I did not need to override the WebClient method to add cookie functionality (however I did research on it and found it to be quite useful for other things).

Thank you very much for helping to solve my problem!

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...