使用Facebook在Azure中进行移动服务身份验证

时间:2012-10-20 19:26:21

标签: authentication facebook-c#-sdk azure-mobile-services

我在Azure中使用移动服务的Facebook身份验证时遇到问题。

更具体地说,我已经有一个使用Facebook C# SDK的应用程序,它运行正常。我可以登录,获取我朋友的列表等等。我想继续使用此SDK,但我还想对Azure Mobile Service进行身份验证。 所以,我的计划是,使用Facebook C#SDK登录(正如我今天所做的那样),获取身份验证令牌,并将其传递给MobileServiceClient.LoginAsync() - 函数。这样,我仍然可以拥有Facebook C#SDK中的所有优秀功能,还可以使用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);

加载完成后,执行以下命令:

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);
}

但是,当我调用上面的最后一行代码时,我得到了这个异常: MobileServiceInvalidOperationException,“错误:POST Facebook登录请求必须在请求正文中指定访问令牌。”

我找不到有关如何格式化accessstoken的任何信息,我尝试了很多不同的键(而不是你在我的示例中看到的“authenticationToken”)。我也尝试过传递accessstoken字符串,但似乎没什么用。 此外,如果我使用MobileServiceClient.LoginAsync()进行全新的登录,它的工作正常,但强制用户登录两次似乎很愚蠢。

非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

对象的预期格式为{“ access_token ”,“the-actual-access-token”}。使用Facebook SDK完成登录后,将在具有该名称的片段中返回令牌,这就是Azure移动服务所期望的。

顺便说一句,这是我写的代码,基于你的代码片段,它可以运行。但它应该更好地处理失败的情况,但对于令牌格式,这应该足够了

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);
        }
    }
}