3

I am having trouble with facebook authentication for Mobile Services in Azure.

To be more specific, I already have an application that is using Facebook C# SDK and it works fine. I can log on, fetch list of my friends and so. I want to keep using this SDK, but I also want to authenticate for Azure Mobile Service. So, my plan was, log on with Facebook C# SDK (as I already do today), get the authentication token, and pass it to the MobileServiceClient.LoginAsync() - function. That way, I can still have all the nice features in Facebook C# SDK, and also use the built in authentication system in Mobile Services for Azure.

var client = new FacebookClient();

dynamic parameters = new ExpandoObject();
parameters.client_id = App.FacebookAppId;
parameters.redirect_uri = "https://www.facebook.com/connect/login_success.html";
parameters.response_type = "token";
parameters.display = "popup";

var loginUrl = client.GetLoginUrl(parameters);
WebView.Navigate(loginUrl);

When load is complete, followin is executed:

FacebookOAuthResult oauthResult;
if (client.TryParseOAuthCallbackUrl(e.Uri, out oauthResult) && oauthResult.IsSuccess)
{
    var accessToken = oauthResult.AccessToken;
    var json = JsonObject.Parse("{\"authenticationToken\" : \"" + accessToken + "\"}");
    var user = await App.MobileService.LoginAsync(MobileServiceAuthenticationProvider.Facebook, json);
}

However, I get this exception when I call the last line of code above: MobileServiceInvalidOperationException, "Error: The POST Facebook login request must specify the access token in the body of the request."

I cannot find any information on how to format the accesstoken, I have tried a lot of different keys (instead of "authenticationToken" as you see in my sample). I also have tried just to pass the accesstoken string, but nothing seem to work. Also, if I use the MobileServiceClient.LoginAsync() for making a brand new login, it works just fine, but it seem silly to force users to log on twice.

Any help is greatly appreciated!

4

1 に答える 1

1

オブジェクトに期待される形式は {" access_token ", "the-actual-access-token"} です。Facebook SDK を使用してログインが完了すると、その名前のフラグメントでトークンが返されるため、Azure Mobile Service はそれを期待しています。

ところで、これはあなたのスニペットに基づいて私が書いたコードで、動作します。ただし、失敗したケースをより適切に処理する必要がありますが、トークン形式の場合はこれで十分です

private void btnLoginFacebookToken_Click_1(object sender, RoutedEventArgs e)
{
    var client = new Facebook.FacebookClient();
    dynamic parameters = new ExpandoObject();
    parameters.client_id = "MY_APPLICATION_CLIENT_ID";
    parameters.redirect_uri = "https://www.facebook.com/connect/login_success.html";
    parameters.response_type = "token";
    parameters.display = "popup";
    var uri = client.GetLoginUrl(parameters);
    this.webView.LoadCompleted += webView_LoadCompleted;
    this.webView.Visibility = Windows.UI.Xaml.Visibility.Visible;
    this.webView.Navigate(uri);
}
async void webView_LoadCompleted(object sender, NavigationEventArgs e)
{
    AddToDebug("NavigationMode: {0}", e.NavigationMode);
    AddToDebug("Uri: {0}", e.Uri);
    string redirect_uri = "https://www.facebook.com/connect/login_success.html";
    bool close = (e.Uri.ToString().StartsWith(redirect_uri));
    if (close)
    {
        this.webView.LoadCompleted -= webView_LoadCompleted;
        this.webView.Visibility = Windows.UI.Xaml.Visibility.Collapsed;
        string fragment = e.Uri.Fragment;
        string accessToken = fragment.Substring("#access_token=".Length);
        accessToken = accessToken.Substring(0, accessToken.IndexOf('&'));
        JsonObject token = new JsonObject();
        token.Add("access_token", JsonValue.CreateStringValue(accessToken));
        try
        {
            var user = await MobileService.LoginAsync(MobileServiceAuthenticationProvider.Facebook, token);
            AddToDebug("Logged in: {0}", user.UserId);
        }
        catch (Exception ex)
        {
            AddToDebug("Error: {0}", ex);
        }
    }
}
于 2012-10-21T16:38:09.713 に答える