如何将Facebook登录v2.0与dotnetopenauth OAuthWebSecurity.RequestAuthentication一起使用
我有一个ASP.Net MVC4应用程序,它是从VS2012中的web模板创建的,因此它使用DotNetOpenAuth和以下代码进行身份验证如何将Facebook登录v2.0与dotnetopenauth OAuthWebSecurity.RequestAuthentication一起使用,facebook,asp.net-mvc-4,Facebook,Asp.net Mvc 4,我有一个ASP.Net MVC4应用程序,它是从VS2012中的web模板创建的,因此它使用DotNetOpenAuth和以下代码进行身份验证 internal class ExternalLoginResult : ActionResult { public ExternalLoginResult(string provider, string returnUrl) { Provider = provider;
internal class ExternalLoginResult : ActionResult
{
public ExternalLoginResult(string provider, string returnUrl)
{
Provider = provider;
ReturnUrl = returnUrl;
}
public string Provider { get; private set; }
public string ReturnUrl { get; private set; }
public override void ExecuteResult(ControllerContext context)
{
OAuthWebSecurity.RequestAuthentication(Provider, ReturnUrl);
}
}
我想使用FacebookLoginV2.0,我可以使用JavaScriptSDK实现这一点,但我无法确定是否可以指定oAuth身份验证的版本
我知道可以在URL中指定v2.0,但我看不到可以在何处配置此URL
有人知道怎么做吗?或者它是硬编码到DotNetOpenAuth中的吗?好的,我找到的解决方案是实现一个定制的OAuth客户端,如下所示(如本文所示) 如您所见,被重写的GetUserData方法引发了一些异常情况。在标准Facebook客户端中,response.username包含用户的Facebook电子邮件地址,但在此实现中data.username包含公共Facebook用户名(时间线地址),这就是我用data.email填充username的原因。这使问题变得复杂,因为一些用户将使用他们的手机而不是他们的电子邮件地址登录,所以我假设response.username(在标准的Facebook客户端中)将返回电子邮件或手机号码,具体取决于用户注册Facebook的方式。那么,我如何决定在此自定义实现中填充用户名的字段?或者使用公共Facebook用户名(时间线地址(例如“joe.blogs.999”)的正确答案是什么?我为什么不这样做
有人有答案吗?我最终决定,如果Facebook没有提供电子邮件地址,我将要求用户在注册过程中输入。我觉得这样更好,因为它允许我使用唯一的电子邮件作为用户的用户名,以本地用户名和密码注册。如果有人想在MVC5中这样做我也有一个解决办法。
using System;
using System.Net;
using System.Collections.Generic;
using System.Web;
using System.Web.Helpers;
using System.Collections.Specialized;
using Newtonsoft.Json;
using System.Web.Script.Serialization;
namespace ExtensionMethods
{
public class FacebookV2Client : DotNetOpenAuth.AspNet.Clients.OAuth2Client
{
private const string AuthorizationEP = "https://www.facebook.com/v2.0/dialog/oauth";
private const string TokenEP = "https://graph.facebook.com/v2.0/oauth/access_token";
private readonly string _appId;
private readonly string _appSecret;
public FacebookV2Client(string appId, string appSecret)
: base("facebook")
{
this._appId = appId;
this._appSecret = appSecret;
}
protected override Uri GetServiceLoginUrl(Uri returnUrl)
{
return new Uri(
AuthorizationEP
+ "?client_id=" + this._appId
+ "&redirect_uri=" + HttpUtility.UrlEncode(returnUrl.ToString())
+ "&scope=email,user_about_me"
+ "&display=page"
);
}
protected override IDictionary<string, string> GetUserData(string accessToken)
{
WebClient client = new WebClient();
string content = client.DownloadString(
"https://graph.facebook.com/me?access_token=" + accessToken
);
dynamic data = Json.Decode(content);
return new Dictionary<string, string> {
{
//The behaviour here is unusual. If you request data.username it holds
//the public Facebook username (Timeline address) instead of the email address that DotetOpenAuth returns as username.
//This complicates matters as some users will login with their mobile rather than their email address so what do we use as username?
"username",
data.email
},
{
"id",
data.id
},
{
"name",
data.name
},
{
"photo",
"https://graph.facebook.com/" + data.id + "/picture"
},
{
"email",
data.email
}
};
}
protected override string QueryAccessToken(Uri returnUrl, string authorizationCode)
{
WebClient client = new WebClient();
string content = client.DownloadString(
TokenEP
+ "?client_id=" + this._appId
+ "&client_secret=" + this._appSecret
+ "&redirect_uri=" + HttpUtility.UrlEncode(returnUrl.ToString())
+ "&code=" + authorizationCode
);
NameValueCollection nameValueCollection = HttpUtility.ParseQueryString(content);
if (nameValueCollection != null)
{
string result = nameValueCollection["access_token"];
return result;
}
return null;
}
}
}
string facebook_appId = "Your appId";
string facebook_appSecret = "Your appSecret";
OAuthWebSecurity.RegisterClient(
new FacebookV2Client(
appId: facebook_appId,
appSecret: facebook_appSecret),
"facebook", null
);