Facebook的Web应用程序扩展权限第二步不显示 [英] Facebook web application extended permissions second step dont show

查看:155
本文介绍了Facebook的Web应用程序扩展权限第二步不显示的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

UPDATE2
这个帖子是老了,但仍然相关。下面是磨片的方法我解决了它。标志着我其他人回答,因为我觉得它回答了这个问题更好。我打电话的AccountController类似的方法(我'约重构:))。该字符串应该是一个列表...我想你得到它。

Update2 This post is getting old but still relevant.. Below is whe way I solved it. I marked the other guys answer because I think it answers the question better. I'm calling a similar method(I'am about to refactor:)) in accountcontroller. The string should be a list... I think you get it.

/// <summary>
    /// 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.
    /// </summary>
    /// <param name="permission"></param>
    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
    }

然后每拨打电话的方法给Facebook一样/我的/ home与Facebok的C#SDK抓住FacebookOAuthException并重定向到folling方法。这就是我们如何运用不是从用户的前面,但在需要的时候问权限的最佳实践。此方法应该有一个匹配以及aredirect url,但我们刚刚走了:)

Then every method making a call to facebook like /me/home with facebok C# SDK catches FacebookOAuthException and redirects to the folling method. This is how we apply the best practise of not asking permissions from users up front but when needed. This method should have aredirect url that matches as well but we've just get going :)

希望它帮助!

/// <summary>
    /// Check for what permissions to request or different ways to handle FacebookOAuthExceptions.
    /// </summary>
    /// <param name="foae">The exception object</param>
    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);
        }
    }

更新:此行为是由在一个密封类范围的硬codeD净OAuth的实现造成的。新增图4显示请求参数,其中缺少的除了电子邮件额外的范围(这是与.NET的OAuth提供所有请求发送)。添加,publish_stream的查询字符串给我想要的行为。任何人都知道如何实现这一目标?

Update: This behaviour is caused by .Net oauth implementation which has the scope hard coded in a sealed class. Added figure 4 to show the request parameter where the lack of additional scopes besides "email"(which is sent with all requests by .net oauth provider). Adding ",publish_stream" to the query string gives me the wanted behaviour. Anyone knows how to achieve this?

请不要提交关于Facebook最佳做法或替代性解决方案的回答或评论。我有一个替代的解决方案,但希望这个默认registerfacebookclient参数工作。我已经更新了应用程序根据两个答案就指定我问什么权限奥菱使用publish_stream。

Please do not submit answers or comments about facebook best practices or alternative solutions. I have an alternative solution but would like this to work with default registerfacebookclient parameters. I have updated the application to oly use publish_stream according to the two answers specifying on what permissions I'm asking for.

图4

figure 4

原题:
我设立这就需要pretty多来自Facebook的所有可用的用户权限的应用程序(C#.Net4.5 MVC4,剃刀视图)。
你可以看到下面我如何设定这一切,code的例子。

Original question: I'm setting up an application (C#.Net4.5 MVC4, razor views) which need pretty much all available user permissions from facebook. You can see code examples below how I have set it all up.

问题是,在图1中点击好的时候,Facebook的送我回我的应用程序。据我所知,应该有一个附加的画面(图2)要求的重的权限。截至目前,我只得到了权限图一是说明。这部分作品...

The problem is that when clicking "okay" in figure 1, Facebook sends me back to my application. As I understand there should be an additional screen(figure2) asking for the "heavier" permissions. As of now I only get the permissions stated in figure one. That part works...

图1

Figure 1

图2

Figure 2

因此​​,使用基本
AuthConfig.cs

So, using basic AuthConfig.cs

var facebooksocialData = new Dictionary<string, object>();
            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一直没有提示扩展权限用户,但只有电子邮件,

This is how I handle the response but here facebook has not prompted the user for the extended permissions but only for email,

AccountController.cs

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]

The closest to an answer I could find was a wp plugin which had the same issue. Their problem was solved by setting domain to localhost. This is how my application is set up. ![enter image description here][4]

推荐答案

我得到了同样的问题。像你一样,我配置了字典RegisterFacebookClient来定义我的应用程序的范围,不幸的是请求中没有包括的范围,因为我配置。于是,我找到<一href=\"http://mvc4beginner.com/Sample-$c$c/Facebook-Twitter/MVC-4-oAuth-Facebook-Login-EMail-Problem-Solved.html\">that.看来,将工作,但它是不够的。于是,我找到<一href=\"http://savvydev.com/authenticating-facebook-users-with-mvc-4-oauth-and-obtaining-scope-permissions/\">this.

I got the same problem. As you did, I configured the RegisterFacebookClient with dictionary to define my app's scope, and unfortunately the request didn't include the scope as I configured. So I found that. It seems that would work, but it wasn't enough. So I found this.

因此​​,这里是什么我解决问题:

So here is what solve my problems:

首先,我添加了这个新的客户到我的code:

First of all I added this new client to my code:

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<string, string> 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<string, string> userData = JsonConvert.DeserializeObject<Dictionary<string, string>>(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<string, string> 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客户端,如下所示:

I put it on a folder "infrastructure" in my asp.net solution with oder stuff, next I change my old configuration, in order to use the new facebook client, as follows:

旧code:

OAuthWebSecurity.RegisterFacebookClient(
appId: "<app-id>",
appSecret: "<app-secret>",
displayName: "Facebook",
extraData: facebookExtraData);

新的code:

OAuthWebSecurity.RegisterClient(
                    new FacebookScopedClient(
                        "<app-id>",
                        "<app-secret>",
                        "scope"), 
                    "Facebook", 
                    null);

就是这样。它可以帮助你,因为帮助了我。

That's it. It may help you, as helped me.

这篇关于Facebook的Web应用程序扩展权限第二步不显示的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆