private void browser_Navigating(object sender, Microsoft.Phone.Controls.NavigatingEventArgs e) { // show the overlay // overlay.Visibility = System.Windows.Visibility.Visible; browser.Visibility = System.Windows.Visibility.Collapsed; // if we somehow got to the home page, redirect to the login page. // this will kick off our login process and result in us getting an access token. // if (FacebookUrls.IsFacebookHome(e.Uri)) { GotoLoginPage(); e.Cancel = true; return; } // if we see the redirect URL that we passed as part of the login process, // we know that we need to start looking for parameters. // if (FacebookUrls.IsRedirectUrl(e.Uri)) { Status = "Processing Login..."; string query = e.Uri.Query; if (!ProcessParams(query)) { e.Cancel = true; } } }
/// <summary> /// This function walks parameters looking for tokens, etc. /// </summary> /// <param name="query"></param> /// <returns></returns> private bool ProcessParams(string query) { // pick out all of the params. Match queryParams = Regex.Match(query, "(?<name>[^?=&]+)(=(?<value>[^&]*)?)"); string access_token = null; string code = null; int expires_in_seconds = -1; bool? fail = null; string error = null; // walk through the matches looking for code, access_token, and expiration. // while (queryParams.Success) { string value = queryParams.Groups["value"].Value; switch (queryParams.Groups["name"].Value) { // Due to the URL # problem in the WebBrowser control, we need to do this process in two steps, // which is to first get a code that we can then exchange for a token. This code parameter is // what we need. // case "code": code = value; string tokenAccessUrl = FacebookUrls.GetTokenUrl(code); // now just use a web request rather than the browser to load up the // actual page that will have the access token.. HttpWebRequest hwr = HttpWebRequest.CreateHttp(tokenAccessUrl); hwr.BeginGetResponse( (asyncObject) => { try { HttpWebResponse resp = (HttpWebResponse)hwr.EndGetResponse(asyncObject); var c = resp.StatusCode; if (c == HttpStatusCode.OK) { string html = new StreamReader(resp.GetResponseStream()).ReadLine(); Dispatcher.BeginInvoke( () => { // recurse with the content of the page. ProcessParams(html); }); } } catch (WebException ex) { Debug.WriteLine(ex.ToString()); } } , null); return(false); case "access_token": access_token = value; fail = false; break; case "state": fail = (value != FacebookUrls.VerificationState); break; case "error": fail = true; break; case "error_description": fail = true; error = value; break; case "expires": expires_in_seconds = int.Parse(value); break; } queryParams = queryParams.NextMatch(); } // if we don't hae a failure and we do have an access token, // fire the completion event. // if (!fail.GetValueOrDefault() && access_token != null) { FacebookLoginEventArgs args = new FacebookLoginEventArgs { AccessToken = access_token, Error = error, Expiration = DateTime.Now.AddSeconds(expires_in_seconds) }; OnComplete(args); } return(true); }