Facebook网络应用程序扩展权限第二步不显示

Update2这篇文章已经老了但仍然相关..下面是我解决它的方式。 我标记了其他人回答,因为我认为它更好地回答了这个问题。 我在accountcontroller中调用了一个类似的方法(我将要重构:))。 字符串应该是一个列表…我想你明白了。

///  /// Use this method when an action fails due to lack of priviligies. It will redirect user to facebook with provided permission request. /// Refactor to handle list of request. ///  ///  private static void AddAdditionalPermissions(string permission) { System.Diagnostics.Trace.TraceInformation(permission + " not authorized for user."); string facebook_urlAuthorize_base = "https://graph.facebook.com/oauth/authorize"; string scope = permission; //see: https://developers.facebook.com/docs/authentication/permissions/ for extended permissions string urlAuthorize = facebook_urlAuthorize_base; urlAuthorize += "?client_id=" + AppId; urlAuthorize += "&redirect_uri=" + "https://fbd.anteckna.nu/"; urlAuthorize += "&scope=" + scope; //redirect the users browser to Facebook to ask the user to authorize our Facebook application HttpContext.Current.Response.Redirect(urlAuthorize, true); //this cannot be done using WebRequest since facebook may need to show dialogs in the users browser } 

然后,使用facebok C#SDK调用facebook / you / home等每个方法捕获FacebookOAuthException并重定向到folling方法。 这就是我们如何应用最佳实践,即不需要事先向用户请求权限,而是在需要时。 此方法应该具有匹配的aredirect url但我们刚刚开始:)

希望能帮助到你!

 ///  /// Check for what permissions to request or different ways to handle FacebookOAuthExceptions. ///  /// The exception object public static void HandleAuthorizationsExceptions(FacebookOAuthException foae) { if (foae.Message.Contains("publish_permissions")) { AddAdditionalPermissions("publish_permissions"); } else if (foae.Message.Contains("read_stream")) { AddAdditionalPermissions("read_stream"); } else { System.Diagnostics.Trace.TraceError("Unhandled error at:" + foae.StackTrace); } } 

更新 :此行为是由.Net oauth实现引起的,其范围在密封类中进行了硬编码。 添加了图4以显示除“email”之外缺少其他范围的请求参数(与.net oauth提供程序的所有请求一起发送)。 在查询字符串中添加“,publish_stream”可以获得想要的行为。 谁知道如何实现这一目标?

请不要提交有关Facebook最佳实践或替代解决方案的答案或评论。 我有一个替代解决方案,但希望这与默认的registerfacebookclient参数一起使用。 我已根据指定我要求的权限的两个答案更新了应用程序以使用publish_stream。

图4 该图显示查询字符串中的范围参数

原始问题:我正在设置一个应用程序(C#.Net4.5 MVC4,razor views),它几乎需要来自facebook的所有可用用户权限。 你可以在下面看到代码示例我如何设置它。

问题是当点击图1中的“好”时,Facebook会将我发回给我的应用程序。 据我所知,应该有一个额外的屏幕(图2)要求“更重”的权限。 截至目前,我只获得了图1中所述的权限。 那部分有效……

图1 Facebook权限对话框C#

图2 在此处输入图像描述

因此,使用基本的AuthConfig.cs

 var facebooksocialData = new Dictionary(); facebooksocialData.Add("scope", "email,publish_stream,read_stream,publish_actions,manage_pages,create_event,offline_access"); OAuthWebSecurity.RegisterFacebookClient( appId: "165359673639901", appSecret: "15091cb2094a1996ae6c7b324f0300e6", displayName: "Facebook", extraData: facebooksocialData); 

这是我处理响应的方式,但这里facebook没有提示用户扩展权限,但仅限于电子邮件,

AccountController.cs

  // // GET: /Account/ExternalLoginCallback [AllowAnonymous] public ActionResult ExternalLoginCallback(string returnUrl) { AuthenticationResult result = OAuthWebSecurity.VerifyAuthentication(Url.Action("ExternalLoginCallback", new { ReturnUrl = returnUrl })); if (!result.IsSuccessful) { return RedirectToAction("ExternalLoginFailure"); } // Save the accesstoken into session Session["accesstoken"] = result.ExtraData["accesstoken"]; Session["id"] = result.ExtraData["id"]; if (OAuthWebSecurity.Login(result.Provider, result.ProviderUserId, createPersistentCookie: false)) { return RedirectToLocal(returnUrl); } if (User.Identity.IsAuthenticated) { // If the current user is logged in add the new account OAuthWebSecurity.CreateOrUpdateAccount(result.Provider, result.ProviderUserId, User.Identity.Name); return RedirectToLocal(returnUrl); } else { // User is new, ask for their desired membership name string loginData = OAuthWebSecurity.SerializeProviderUserId(result.Provider, result.ProviderUserId); ViewBag.ProviderDisplayName = OAuthWebSecurity.GetOAuthClientData(result.Provider).DisplayName; ViewBag.ReturnUrl = returnUrl; return View("ExternalLoginConfirmation", new RegisterExternalLoginModel { UserName = result.UserName, ExternalLoginData = loginData }); } } 

最接近我能找到的答案是一个wp插件,它有同样的问题。 他们的问题通过将域设置为localhost来解决。 这就是我的应用程序的设置方式。 ![在此输入图像说明] [4]

我遇到了同样的问题。 正如您所做的那样,我使用字典配置了RegisterFacebookClient以定义我的应用程序的范围,不幸的是,请求不包括我配置的范围。 所以我找到了 。 这似乎有用,但还不够。 所以我找到了这个 。

所以这就解决了我的问题:

首先,我将这个新客户端添加到我的代码中:

 using System; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Text.RegularExpressions; using System.Web; using DotNetOpenAuth.AspNet; using Newtonsoft.Json; namespace MyApp.UI.Infrastructure { public class FacebookScopedClient : IAuthenticationClient { private string appId; private string appSecret; private string scope; private const string baseUrl = "https://www.facebook.com/dialog/oauth?client_id="; public const string graphApiToken = "https://graph.facebook.com/oauth/access_token?"; public const string graphApiMe = "https://graph.facebook.com/me?"; private static string GetHTML(string URL) { string connectionString = URL; try { System.Net.HttpWebRequest myRequest = (HttpWebRequest)WebRequest.Create(connectionString); myRequest.Credentials = CredentialCache.DefaultCredentials; //// Get the response WebResponse webResponse = myRequest.GetResponse(); Stream respStream = webResponse.GetResponseStream(); //// StreamReader ioStream = new StreamReader(respStream); string pageContent = ioStream.ReadToEnd(); //// Close streams ioStream.Close(); respStream.Close(); return pageContent; } catch (Exception) { } return null; } private IDictionary GetUserData(string accessCode, string redirectURI) { string token = GetHTML(graphApiToken + "client_id=" + appId + "&redirect_uri=" + HttpUtility.UrlEncode(redirectURI) + "&client_secret=" + appSecret + "&code=" + accessCode); if (token == null || token == "") { return null; } string access_token = token.Substring(token.IndexOf("access_token="), token.IndexOf("&")); string data = GetHTML(graphApiMe + "fields=id,name,email,username,gender,link&" + access_token); // this dictionary must contains Dictionary userData = JsonConvert.DeserializeObject>(data); return userData; } public FacebookScopedClient(string appId, string appSecret, string scope) { this.appId = appId; this.appSecret = appSecret; this.scope = scope; } public string ProviderName { get { return "facebook"; } } public void RequestAuthentication(System.Web.HttpContextBase context, Uri returnUrl) { string url = baseUrl + appId + "&redirect_uri=" + HttpUtility.UrlEncode(returnUrl.ToString()) + "&scope=" + scope; context.Response.Redirect(url); } public AuthenticationResult VerifyAuthentication(System.Web.HttpContextBase context) { string code = context.Request.QueryString["code"]; string rawUrl = context.Request.Url.OriginalString; //From this we need to remove code portion rawUrl = Regex.Replace(rawUrl, "&code=[^&]*", ""); IDictionary userData = GetUserData(code, rawUrl); if (userData == null) return new AuthenticationResult(false, ProviderName, null, null, null); string id = userData["id"]; string username = userData["username"]; userData.Remove("id"); userData.Remove("username"); AuthenticationResult result = new AuthenticationResult(true, ProviderName, id, username, userData); return result; } } } 

我把它放在我的asp.net解决方案中的“基础设施”文件夹中,然后我改变了我的旧配置,以便使用新的facebook客户端,如下所示:

旧代码:

 OAuthWebSecurity.RegisterFacebookClient( appId: "", appSecret: "", displayName: "Facebook", extraData: facebookExtraData); 

新代码:

 OAuthWebSecurity.RegisterClient( new FacebookScopedClient( "", "", "scope"), "Facebook", null); 

而已。 它对你有帮助,对我有所帮助。

您的应用是否已注册这些范围? 我熟悉Google OAuth,他们有一个单独的范围映射到一个权限。 您的应用应该注册范围,以获得第二个窗口。 否则,您只能访问第一个弹出窗口要求的公共信息。

首先, offline_access不再存在,因此它来自您要求的权限。

“[app]几乎需要来自facebook的所有可用用户权限”

Facebook积极阻止直接从一开始就要求大量的权限“以防万一”因为以后可能需要它们。 只有在用户刚刚第一次触发的操作实际需要时,才应该要求扩展权限。

此外,您应该分别要求“读取”和“写入”权限。

我不知道这些方面是否真的引发了您的错误 – 但我知道Facebook已经发送了读/写事件的开发人员警报; 虽然FB员工确认现在可以忽略这些警报,但他们可能会在将来的某个时候开始执行此警报。