C# Facebook.NETSDK:如何使用ASP.NETMVC2进行身份验证
我试图掌握Facebook SDK,同时从ASP.NET表单过渡到MVC(最终)。所以请容忍我 我创建了两个控制器操作: 当用户单击表单上的FB登录按钮时,将执行FBLogon。 然后他被重定向到FB登录页面 之后,他被发送回FBAuthorize页面,该页面应该解析访问令牌返回的url。我得到的结果是: 我看到的问题是,由于access_令牌是在一个#后面传递的,asp.net无法在服务器上解析它。我做错什么了吗 代码如下:C# Facebook.NETSDK:如何使用ASP.NETMVC2进行身份验证,c#,facebook,authentication,facebook-c#-sdk,C#,Facebook,Authentication,Facebook C# Sdk,我试图掌握Facebook SDK,同时从ASP.NET表单过渡到MVC(最终)。所以请容忍我 我创建了两个控制器操作: 当用户单击表单上的FB登录按钮时,将执行FBLogon。 然后他被重定向到FB登录页面 之后,他被发送回FBAuthorize页面,该页面应该解析访问令牌返回的url。我得到的结果是: 我看到的问题是,由于access_令牌是在一个#后面传递的,asp.net无法在服务器上解析它。我做错什么了吗 代码如下: public ActionResult FBLogon()
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<string, object>
{
{ "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();
}
public ActionResult fbloon()
{
var settings=ConfigurationManager.GetSection(“facebookSettings”);
IFacebookApplication当前值=空;
如果(设置!=null)
{
当前=设置为iFaceBook应用程序;
if(current.AppId==“{app id}”| | current.AppSecret==“{app secret}”)
{
返回视图();
}
}
string[]extendedPermissions=new[]{“发布\流”,“脱机\访问”};
var oauth=new-facebookouthclient{ClientId=current.AppId,RedirectUri=new-Uri('http://localhost:5000/account/FBAuthorize") };
var参数=新字典
{
{“响应类型”,“令牌”},
{“显示”,“页面”}
};
if(extendedpowpermissions!=null&&extendedpowpermissions.Length>0)
{
var scope=新的StringBuilder();
Append(string.Join(“,”,extendedPermissions));
参数[“scope”]=scope.ToString();
}
var loginUrl=oauth.GetLoginUrl(参数);
返回重定向(loginUrl.ToString());
}
公共行动结果FBAuthorize()
{
FaceBookOuthResult结果;
if(facebookouthresult.TryParse(Request.Url,out result))
{
如果(结果。发布成功)
{
var accesstoken=result.accesstoken;
}
其他的
{
var errorDescription=result.errorDescription;
var errorReason=result.errorReason;
}
}
返回视图();
}
好的。facebook文档非常清楚地说:
因为访问令牌是传入的
URI片段,仅客户端代码
(例如在
承载web的浏览器或桌面代码
控件)可以检索令牌。应用程序
通过验证来处理身份验证
重定向uri是否处于相同的位置
域作为在中配置的站点URL
开发者应用程序
来自--->客户端流部分
因此,我将令牌发送回我的服务器以完成身份验证
更新:
我使用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;
}
我和你现在在同一个地方。 由于url中的“片段”或#,我们从未填充Request.QueryString 我很想知道你是否解决了这个问题,以及如何解决 它看起来不像FacebookOAuthResult类是为在任何类型的web应用程序中使用而编写的 您可以将作用域参数中的响应类型更改为“code”,然后它将在查询字符串中发回一个代码,您可以在其中交换令牌。我在codeplex上找到了这篇文章。我想这就是你需要的 请注意,您需要使用服务器端流,而不是使用客户端流 这是你应该做的 为服务器端流创建登录链接。授权后,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<string, object>();
//parameters.Add("permissions", "offline_access");
Dictionary<String, Object> dict = (Dictionary<String, Object>)cl.ExchangeCodeForAccessToken(code, new Dictionary<string, object> { { "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();
}
public ActionResult FBAuthorize()
{
FacebookOAuthClient cl=新的FacebookOAuthClient(FacebookContext.Current);
FacebookOAuthResult结果=null;
字符串url=Request.url.OriginalString;
//验证url中是否有代码
if(FacebookOAuthResult.TryParse(url,输出结果))
{
如果(结果。发布成功)
{
字符串代码=result.code;
//这一行是必要的,直到他们修复了一个错误*见下面的详细信息
cl.RedirectUri=新的UriBuilder(“http://localhost:5000/account/FBAuthorize.Uri;
var参数=新字典();
//添加(“权限”、“脱机访问”);
Dictionary dict=(Dictionary)cl.ExchangeCodeForAccessToken(代码,新字典{{“重定向uri”,”http://localhost:5000/account/FBAuthorize" } });
对象标记=dict.Values.ElementAt(0);
TempData[“accessToken”]=Token.ToString();
返回重定向到操作(“ShowUser”);
}
其他的
{
var errorDescription=result.errorDescription;
}
}
其他的
{
//TODO:句柄错误
}
返回视图();
}
*在localhost中使用IIS时存在错误,有关详细信息,请参阅原始帖子(请求令牌时的重定向uri必须与请求代码时使用的重定向uri相同)
强烈建议使用IIS而不是visual studio web server。在visual studio web server中有许多东西无法工作。更新了我的答案。(顺便说一句,你的回答应该是评论)很棒的东西。坚持服务器端流程是关键。
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<string, object>();
//parameters.Add("permissions", "offline_access");
Dictionary<String, Object> dict = (Dictionary<String, Object>)cl.ExchangeCodeForAccessToken(code, new Dictionary<string, object> { { "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();
}