Facebook .NET SDK:如何使用ASP.NET MVC 2进行身份validation

我试图掌握Facebook SDK,同时从ASP.NET表单转换到MVC(最后)。 所以请耐心等待..

我创建了两个控制器动作:

当用户单击表单上的FB登录按钮时,将取消FBLogon。 然后他被重定向到FB登录页面。

之后,他被送回FBAuthorize页面,该页面应该解析返回的URL以获取访问令牌。 我有类似的东西:

HTTP://本地主机:5000 /帐户/ FBAuthorize#=的access_token 199143326771791 | 827213759889396d5408fee6-100001815992604 | BmYchAOMqSoZ2L0TYgCrtpoKP3M&expires_in = 0

我看到的问题是,当access_token在#后面传递时,asp.net无法在服务器上解析它。 我做的事情基本上是错误的吗?

代码如下:

public ActionResult FBLogon() { var settings = ConfigurationManager.GetSection("facebookSettings"); IFacebookApplication current = null; if (settings != null) { current = settings as IFacebookApplication; if (current.AppId == "{app id}" || current.AppSecret == "{app secret}") { return View(); } } string[] extendedPermissions = new[] { "publish_stream", "offline_access" }; var oauth = new FacebookOAuthClient { ClientId = current.AppId, RedirectUri = new Uri("http://localhost:5000/account/FBAuthorize") }; var parameters = new Dictionary { { "response_type", "token" }, { "display", "page" } }; if (extendedPermissions != null && extendedPermissions.Length > 0) { var scope = new StringBuilder(); scope.Append(string.Join(",", extendedPermissions)); parameters["scope"] = scope.ToString(); } var loginUrl = oauth.GetLoginUrl(parameters); return Redirect(loginUrl.ToString()); } public ActionResult FBAuthorize() { FacebookOAuthResult result; if (FacebookOAuthResult.TryParse(Request.Url, out result)) { if (result.IsSuccess) { var accesstoken = result.AccessToken; } else { var errorDescription = result.ErrorDescription; var errorReason = result.ErrorReason; } } return View(); } 

我在codeplex上发现了这篇文章http://facebooksdk.codeplex.com/discussions/244568 。 我想这就是你需要的。

请注意,您需要使用服务器端流程,而不是使用客户端流程。

这是你应该做的

为服务器端流创建登录链接。 授权后,Facebook将返回包含代码而不是访问令牌的URL。

然后,您使用代码从facebook请求令牌。 这是我的榜样

  public ActionResult FBAuthorize() { FacebookOAuthClient cl = new FacebookOAuthClient(FacebookContext.Current); FacebookOAuthResult result = null; string url = Request.Url.OriginalString; // verify that there is a code in the url if (FacebookOAuthResult.TryParse(url, out result)) { if (result.IsSuccess) { string code = result.Code; // this line is necessary till they fix a bug *see details below cl.RedirectUri = new UriBuilder("http://localhost:5000/account/FBAuthorize").Uri; var parameters = new Dictionary(); //parameters.Add("permissions", "offline_access"); Dictionary dict = (Dictionary)cl.ExchangeCodeForAccessToken(code, new Dictionary { { "redirect_uri", "http://localhost:5000/account/FBAuthorize" } }); Object Token = dict.Values.ElementAt(0); TempData["accessToken"] = Token.ToString(); return RedirectToAction ("ShowUser"); } else { var errorDescription = result.ErrorDescription; } } else { // TODO: handle error } return View(); } 

*在localhost中使用IIS时存在错误,请参阅原始post了解详细信息(请求令牌时的重定向uri必须与要求代码的用户相同)

强烈建议使用IIS而不是visual studio Web服务器。 有许多东西在visual studio web服务器中不起作用。

好。 Facebook文档非常清楚地说:

因为访问令牌是在URI片段中传递的,所以只有客户端代码(例如在浏览器中执行的JavaScript或托管Web控件的桌面代码)才能检索令牌。 通过validationredirect_uri与Developer App中配置的站点URL位于同一域中来处理应用程序身份validation

来自http://developers.facebook.com/docs/authentication/ —>客户端流程部分。

所以我将令牌发送回我的服务器以完成身份validation。

更新:

使用Javascript这样发送回服务器:

  var appId = "<%: Facebook.FacebookContext.Current.AppId %>"; if (window.location.hash.length > 0) { accessToken = window.location.hash.substring(1); var url = window.location.href.replace(/#/, '?'); window.location = url; } 

在服务器上,然后我有以下操作。 不是很好,但它的工作..

 public ActionResult FBAuthorize() { FacebookOAuthResult result = null; string url = Request.Url.OriginalString; /// hack to make FacebookOuthResult accept the token.. url = url.Replace("FBAuthorize?", "FBAuthorize#"); if (FacebookOAuthResult.TryParse(url, out result)) { if (result.IsSuccess) { string[] extendedPermissions = new[] { "user_about_me", "offline_access" }; var fb = new FacebookClient(result.AccessToken); dynamic resultGet = fb.Get("/me"); var name = resultGet.name; RegisterModel rm = new Models.RegisterModel(); rm.UserName = name; rm.Password = "something"; rm.Email = "somethig"; rm.ConfirmPassword = "23213"; //Label1.Text = name; //Response.Write(name); //return RedirectToAction("register", "Account", rm); ViewData["Register"] = rm; return RedirectToAction("Register"); } else { var errorDescription = result.ErrorDescription; var errorReason = result.ErrorReason; } } return View(); } 

我现在和你在同一个地方。 我们永远不会得到Request.QueryString,因为url中存在“fragment”或#。

很高兴知道你是否解决了这个以及如何解决

看起来FacebookOAuthResult类似乎不是用于任何类型的Web应用程序。

您可以将范围paramas中的响应类型更改为“code”,然后它将在querystring中发回代码,您可以在其中交换令牌。