【问题标题】:WebApi: How to call Facebook Graph API by using an access token originated from the OAuth dialogWebApi:如何使用源自 OAuth 对话框的访问令牌调用 Facebook Graph API
【发布时间】:2014-11-27 04:13:39
【问题描述】:

我有一个配置了 OAuth2 的 ASP.NET WebApi 2.1 应用程序。我有 Android 客户端,可以使用以下方法进行身份验证:

WebView 方法(Web Api 外部提供者):重定向到https://www.facebook.com/dialog/oauth...,用户在那里登录,FB 请求权限,重定向到我的 url,捕获它,获取访问令牌,完成。

Facebook SDK 方法:在后台:重定向到 https://graph.facebook.com/oauth...,用户在那里登录,FB 请求权限,重定向到我的 url,捕获它,获取访问令牌,完成。

问题是,如果我使用 WebView 版本,令牌很适合在我的 Web Api 应用程序中授权用户,但我无法使用它调用 Graph API,我收到 OAuthException 190(无子代码)。

但是,如果我进行 SDK 授权,则可以访问 Graph API(通过 Android Facebook SDK),但是使用我从中获得的令牌,Web Api 授权不起作用,我通过调用 Authorization/UserInfo 得到 401。

所以我的问题是上述令牌类型可以以某种方式互换吗?

任何帮助将不胜感激。

【问题讨论】:

  • 我不知道您所说的配置的 OAuth2 Web API 到底是什么意思您是否使用 Web API 个人帐户模板?我之前已经发布了我们如何获取 FB 令牌(外部访问令牌),然后将其替换为本地访问令牌(由本地权限生成)。所以你现在有 2 个令牌,本地的一个适合 Web API,外部的一个适合调用 FB 图形 API。在这里查看bitoftech.net/2014/08/11/…
  • 谢谢,您的评论帮助我找到了适合我正在使用的项目模板的解决方案。我在下面解释了我的解决方案。
  • 不客气,如果有用请给我的评论投票。
  • 我还没有足够的声望来支持 cmets,对不起!我保证我一回来就回来。

标签: android facebook facebook-graph-api asp.net-web-api oauth


【解决方案1】:

抱歉,如果不清楚,我正在使用带有 ASP.NET Identity 2.0 模板的 Web Api,因此 OAuth 管道代码已经存在。

我已经找到了我自己问题的答案,让我与你分享。

所以问题是我在重定向后从 Facebook 的 OAuth 对话框获得的令牌与我的应用程序可以用来以实际用户的名义调用 Facebook Graph API 的令牌不同。该 Graph API 令牌可在以下位置访问:

假设您使用上面提到的模板,您可以找到 App_Data/Startup.Auth.cs 类,其中定义了 FacebookAuthenticationOptions 实例。在那里,您可以捕获 API 令牌并将其保存到数据库中。例如:

var fbopts = new FacebookAuthenticationOptions
{
    AppId = Global.Config.ExternalServices.FacebookAppID,
    AppSecret = Global.Config.ExternalServices.FacebookAppSecret,
    Scope = { "email", "user_friends", "publish_actions" },
    Provider = new FacebookAuthenticationProvider
    {
        OnAuthenticated = async context =>
        {
            // This token will be OK for calling Graph API
            string accessToken = context.AccessToken; 

            using (var tracer = Global.Tracer.CreateBuilder())
            {
                try
                {
                    tracer.InformationLine("Storing Facebook OAuth token: " + accessToken);
                    string fbUserID = context.Identity.GetUserId();
                    string fbUserName = context.Identity.Name;
                    tracer.InformationLine("Facebook User ID: " + fbUserID);
                    tracer.InformationLine("Facebook User Name: " + fbUserName);

                    // Store it into the db
                    // assume Task StoreOAuthToken(string providerName, string providerKey, string accessToken) is defined
                    await StoreOAuthToken("Facebook", fbUserID, accessToken);                       
                }
                catch (Exception ex)
                {
                    tracer.ErrorLine("Failed.", ex);
                }
            }
        }
    }
};
app.UseFacebookAuthentication(fbopts);

此时,您将在包含以下列的表格中拥有一行:

OAuthAccessToken.ProviderName
OAuthAccessToken.ProviderKey
OAuthAccessToken.AccessToken

现在您可以向您的消费者提供一个 API,以获得该 API 令牌来调用 Graph API,例如:

[Route("AccessTokens")]
[Authorize]
public async Task<List<OAuthAccessToken>> GetAccessTokens(string providerName = null)
{
    var userID = User.Identity.GetUserId();

    var q = from l in this.Context.AspNetUserLogins // Managed by ASP.NET Identity 2.0
            from t in this.Context.OAuthAccessTokens // Stored by you with above code
            where l.UserId == userID && t.ProviderName == l.LoginProvider && t.ProviderKey == l.ProviderKey
            select t;

    if (!string.IsNullOrEmpty(providerName)) q = q.Where(t => t.ProviderName == providerName);

    return await q.ToListAsync();
}

因此,在 Android 上,在登录 Facebook 后,我获得了用于应用程序 Web Api 调用的 Bearer 令牌,并且我可以通过调用上述操作来获取用于访问 Graph API 的令牌。

也许有更简单的方法可以实现上述目标。如果你找到了请告诉我。

【讨论】:

    猜你喜欢
    • 2011-11-06
    • 1970-01-01
    • 1970-01-01
    • 2014-11-07
    • 2012-03-04
    • 1970-01-01
    • 1970-01-01
    • 2013-12-09
    • 1970-01-01
    相关资源
    最近更新 更多