gpt4 book ai didi

c# - Facebook web 应用程序扩展权限第二步不显示

转载 作者:可可西里 更新时间:2023-11-01 08:45:36 25 4
gpt4 key购买 nike

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

/// <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
}

然后,使用 facebok C# SDK 调用 facebook(如/me/home)的每个方法都会捕获 FacebookOAuthException 并重定向到以下方法。这就是我们应用最佳实践的方式,即不预先征求用户许可,而是在需要时征求用户许可。此方法也应具有匹配的重定向 url,但我们才刚刚开始:)

希望对您有所帮助!

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

更新:此行为是由 .Net oauth 实现引起的,该实现的范围硬编码在密封类中。添加了图 4 以显示请求参数,其中除了“电子邮件”(由 .net oauth 提供程序随所有请求一起发送)之外缺少其他范围。将“,publish_stream”添加到查询字符串会给我想要的行为。任何人都知道如何实现这一点?

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

图 4 Image showing scope parameter in query string

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

问题是,当单击图 1 中的“确定”时,Facebook 将我发送回我的应用程序。据我所知,应该有一个额外的屏幕(图 2)要求“更重”的权限。到目前为止,我只获得了图一中所述的权限。那部分工作...

图1 Facebook permissions dialog C#

图2 enter image description here

所以,使用基本的授权配置.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 没有提示用户扩展权限,而只提示电子邮件,

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 插件,它有同样的问题。他们的问题通过将域设置为本地主机来解决。这就是我的应用程序的设置方式。

最佳答案

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

所以这是解决我的问题的方法:

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

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 解决方案中的文件夹“infrastructure”中,接下来我更改我的旧配置,以便使用新的 facebook 客户端,如下所示:

旧代码:

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

新代码:

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

就是这样。它可能对您有所帮助,就像对我有所帮助一样。

关于c# - Facebook web 应用程序扩展权限第二步不显示,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16717002/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com