1
votes

I'm trying out a "login with facebook" feature for a Windows Phone app. I have a very small prototype with a button and a webbrowser on a page. Clicking on the button directs the browser to a URL specified by the Facebook API in order to authorize an app with the details of the currently logged in user.

    <Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto"></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>

        <Button Click="ButtonBase_OnClick">Clic</Button>

        <phone:WebBrowser Grid.Row="1" x:Name="webBrowser" Navigated="WebBrowser_OnNavigated"/>
    </Grid>

The code behind looks like so :

    private const string AppId = "123456"; // In my code I've put the correct App ID.

    private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
    {
        webBrowser.Navigate(new Uri("https://www.facebook.com/dialog/oauth?client_id=" + AppId + "&redirect_uri=" + Uri.EscapeUriString(@"https://www.facebook.com/connect/login_success.html")));
    }

    private void WebBrowser_OnNavigated(object sender, NavigationEventArgs e)
    {
        var x = e.Uri.ToString();
    } // BreakPoint set here to inspect 'x'

This exact piece of code placed in a WPF application works as expected. That is, if I haven't authorized the app yet, the first hit on the 'OnNavigated' event handler reflects the URL above and then, after authorization, has a URL containing an authorization token. Here's the URLs and steps when I run it as a WPF app :

A. Start the app, clic the button :

https://www.facebook.com/dialog/oauth?client_id=123456&redirect_uri=https://www.facebook.com/connect/login_success.html

Now I get presented with the "[your_app_name] will receive the following information about you : public profile and friends list". I click OK.

B. I am getting redirected to :

=">https://www.facebook.com/connect/login_success.html?code=AQAOJ7H6lK7dsRCJPRjVRVPZmxQrZ7ksWyqb87MfagEc1eatw_1n4ijY0IpDmbVQEg6Un3nmrvzhiiynM4S_l5S_ChgD7ZOVSf-JvxyD8S5sCHFUtBZ9H8lCrT0Lh7aRDgKW1u1XbWuUfcbXl2i6FndWG9Svk9bssRq7F4O-XrPsnK--b31qrFLptzrA0saC1stWoMhyR9vXkiLevxADQ7GHpeGQeu29mOhIaXWBtJy1Wlvins346kNR8Pi77wwpwAt5BzYsTRXdbYxbFdAPDJI2RJyqv4IMKGR0BucmtX9lrmBWcfJeMLzMag-GNDJ5I4U#=

(I've changed a few characters in the token above in order to protect my privacy)


Now this is great and it's what I need. I'll take the very same code and place it in a Windows Phone 7.1 app and the behavior changes like so :

First the URL differs, probably because it detects a mobile (touch) device :

A. Click the button :

https://m.facebook.com/login.php?skip_api_login=1&api_key=123456&signed_next=1&next=https://m.facebook.com/dialog/oauth?redirect_uri=https%253A%252F%252Fwww.facebook.com%252Fconnect%252Flogin_success.html&client_id=123456&ret=login&cancel_uri=https://www.facebook.com/connect/login_success.html?error=access_denied&error_code=200&error_description=Permissions+error&error_reason=user_denied%23_=_&display=touch&_rdr

Now I'm getting to the login page so I first login into facebook. I hit login.

B. I am getting to :

rdr#=_">https://m.facebook.com/dialog/oauth?redirect_uri=https://www.facebook.com/connect/login_success.html&client_id=123456&ret=login&ext=1391596741&hash=AeYEMbLJMwI3QhOE&refsrc=https://m.facebook.com/login.php&refid=9&m_sess=c2VzczoxMDAwMDAwOTg1MjE5NzM6MzM6Ti13TjN3eUERd3ZrR1E6MjoxMzkxNTkzMTQxOjMwODE&rdr#=_

At this page I am getting asked if I want to authorize the app. I click OK.

C. I get redirected to https://m.facebook.com/dialog/oauth/read (no other querystring). This is my issue


At this point I'm stumped since I have no auth token. A workaround is to try redirecting the browser again to the first URL (see ButtonBase_OnClick) and that will work.

That means changing the OnNavigated event handler to :

    private void WebBrowser_OnNavigated(object sender, NavigationEventArgs e)
    {
        var x = e.Uri.ToString();

        if (x == @"https://m.facebook.com/dialog/oauth/read")
        {
            ButtonBase_OnClick(sender, new RoutedEventArgs());
        }
    }

But that requires ANOTHER request and it definetely feels like a hack.

Am I doing something wrong? Is the app not configured properly?

2
Maybe it's just shoot in the dark - but can you try to enable scripts in your webbrowser Webbrowser.IsScriptEnabled = true; (AFAIK by default switched off). Maybe it will help - Romasz
did you try using different redirect URL? your server, or even localhost:43281 (need to have a thread listening for the request on port 43281 though)? EDIT - port is just random number of course, only for illustration purposes. - avs099
No, I haven't tried using a different URL because on the facebook developer's site clearly says that for a desktop/mobile app you need to provide exactly that URL as a redirect. - Andrei Rînea

2 Answers

1
votes

I had these working for my WP7.5 app which worked in WP8 too. It was using graph api before this Facebook SDk for .Net was born.

string strLoginURL = "https://graph.facebook.com/oauth/authorize?client_id={0}&redirect_uri=http://www.facebook.com/connect/login_success.html&type=user_agent&display=touch&scope=publish_stream,user_hometown";
string strAppID = "123456789101112";
string strPostMessageURL = "https://graph.facebook.com/yourpageid/feed";
    string strAccessToken = String.Empty;

private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
    webBrowser.Navigate(new Uri(string.Format(strLoginURL, strAppID), UriKind.Absolute));
}

private void webBrowser_LoadCompleted(object sender, NavigationEventArgs e)
{
    string strSourceString = objAuthorizeBrowserControl.Source.ToString();
    //string strSourceString = e.Uri.OriginalString.ToLower();

    if (strSourceString.Contains("access_token"))
    {
            int index1 = strSourceString.IndexOf("access_token");
            int index2 = strSourceString.IndexOf("expires_in");
            strAccessToken = strSourceString.Substring(index1 + 13, index2 - (index1 + 14));    
    }
    /*...
    else
        logging in and authorize app will get redirected automatically untill access token is generated.
    ...*/

    if(strAccessToken != String.Empty)
    {
        WebClient wc = new WebClient();
        string strParametersToPost = "access_token=" + strAccessToken + "&message=" + HttpUtility.UrlEncode(yourcontenttopost); 
        wc.UploadStringAsync(strPostMessageURL, "POST", strParametersToPost);
        // you can use wc.UploadStringCompleted Event to capture the result.
    }
}

private void webBrowser_Navigating(object sender, NavigatingEventArgs e)
{
    string strSourceString = objAuthorizeBrowserControl.Source.ToString();
    //string strSourceString = e.Uri.OriginalString.ToLower();

    if (strSourceString.Contains("access_token"))
    {
        int index1 = strSourceString.IndexOf("access_token");
        int index2 = strSourceString.IndexOf("expires_in");
        strAccessToken = strSourceString.Substring(index1 + 13, index2 - (index1 + 14));
    }
}
1
votes

Why are you using the old method Use this: http://facebooksdk.net/docs/phone/tutorial/, And this is also a very simple method it will take you around 1-2 hours to setup.
And I am using it in my app and it is working great for me I am registering the user through this in my app and storing all the details.