我知道,“姓名”字段提供的,但我更愿意明确地访问姓和名。有人能帮助呢?我还在我的包裹周围ASP.Net MVC头部。
在您的Startup.Auth.cs ConfigureAuth(IAppBuilder app)
方法,设置为Facebook如下:
var x = new FacebookAuthenticationOptions();
x.Scope.Add("email");
x.AppId = "*";
x.AppSecret = "**";
x.Provider = new FacebookAuthenticationProvider()
{
OnAuthenticated = async context =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
foreach (var claim in context.User)
{
var claimType = string.Format("urn:facebook:{0}", claim.Key);
string claimValue = claim.Value.ToString();
if (!context.Identity.HasClaim(claimType, claimValue))
context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Facebook"));
}
}
};
x.SignInAsAuthenticationType = DefaultAuthenticationTypes.ExternalCookie;
app.UseFacebookAuthentication(x);
/*
app.UseFacebookAuthentication(
appId: "*",
appSecret: "*");
* */
然后用它来访问用户的登录信息:
var loginInfo = await AuthenticationManager.GetExternalLoginInfoAsync();
然后将下面的拿到的第一个名字:
var firstNameClaim = loginInfo.ExternalIdentity.Claims.First(c => c.Type == "urn:facebook:first_name");
Facebook的改变了它的权限的API。你可以在这里获得更多的信息:https://developers.facebook.com/docs/facebook-login/permissions
名称需要public_profile许可
var facebookAuthenticationOptions = new FacebookAuthenticationOptions()
{
AppId = "appId",
AppSecret = "key"
};
facebookAuthenticationOptions.Scope.Add("email");
facebookAuthenticationOptions.Scope.Add("public_profile");
app.UseFacebookAuthentication(facebookAuthenticationOptions);
你可以用得到它:
var loginInfo = await authenticationManager.GetExternalLoginInfoAsync();
loginInfo.ExternalIdentity.Claims.First(c => c.Type == "urn:facebook:name")
AuthenticationManager会是一个实例,你可以使用:
HttpContext.GetOwinContext().Authentication;
不幸的是,因为Facebook的改变了他们的默认返回值与API更新2.4这个方法行不通了
它看起来像得到FIRST_NAME等的唯一方法是现在使用Facebook的图形API(like this posts suggests)。
我还发现this post的武士刀项目现场,解决这个问题,并已经提交pull请求,但尚未合并喷射。
希望这个保险柜别人的一点点时间;)
2017年,这是为我工作(感谢David Poxon的码以上)的代码。请确保您已升级到Microsoft.Owin.Security.Facebook
的3.1.0版本。
在Startup.Auth.cs(或Startup.cs在某些情况下),将以下代码:
app.UseFacebookAuthentication(new FacebookAuthenticationOptions()
{
AppId = "***",
AppSecret = "****",
BackchannelHttpHandler = new HttpClientHandler(),
UserInformationEndpoint = "https://graph.facebook.com/v2.8/me?fields=id,name,email,first_name,last_name",
Scope = { "email" },
Provider = new FacebookAuthenticationProvider()
{
OnAuthenticated = async context =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
foreach (var claim in context.User)
{
var claimType = string.Format("urn:facebook:{0}", claim.Key);
string claimValue = claim.Value.ToString();
if (!context.Identity.HasClaim(claimType, claimValue))
context.Identity.AddClaim(new System.Security.Claims.Claim(claimType, claimValue, "XmlSchemaString", "Facebook"));
}
}
}
});
然后在您的控制器的外部登录回调方法,添加以下代码:
var firstName = loginInfo.ExternalIdentity.Claims.First(c => c.Type == "urn:facebook:first_name").Value;
同样,对于获得姓氏,用上面的线,代之以urn:facebook:first_name
的urn:facebook:last_name
private Uri RedirectUri
{
get
{
var uriBuilder = new UriBuilder(Request.Url);
uriBuilder.Query = null;
uriBuilder.Fragment = null;
uriBuilder.Path = Url.Action("FacebookCallback");
return uriBuilder.Uri;
}
}
[AllowAnonymous]
public ActionResult Facebook()
{
var fb = new FacebookClient();
var loginUrl = fb.GetLoginUrl(new
{
client_id = "296002327404***",
client_secret = "4614cd636ed2029436f75c77961a8***",
redirect_uri = RedirectUri.AbsoluteUri,
response_type = "code",
scope = "email" // Add other permissions as needed
});
return Redirect(loginUrl.AbsoluteUri);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult LogOff()
{
FormsAuthentication.SignOut();
return View("Login");
}
public ActionResult FacebookCallback(string code)
{
var fb = new FacebookClient();
dynamic result = fb.Post("oauth/access_token", new
{
client_id = "296002327404***",
client_secret = "4614cd636ed2029436f75c77961a8***",
redirect_uri = RedirectUri.AbsoluteUri,
code = code
});
var accessToken = result.access_token;
// Store the access token in the session for farther use
Session["AccessToken"] = accessToken;
// update the facebook client with the access token so
// we can make requests on behalf of the user
fb.AccessToken = accessToken;
// Get the user's information
dynamic me = fb.Get("me?fields=first_name,middle_name,last_name,id,email");
string email = me.email;
string firstname = me.first_name;
string middlename = me.middle_name;
string lastname = me.last_name;
db.Insert_customer(firstname,email,null,null,null,null,null,null,null,null,null,null,1,1,System.DateTime.Now,1,System.DateTime.Now);
// Set the auth cookie
FormsAuthentication.SetAuthCookie(email, false);
return RedirectToAction("Index", "Home");
}
}
}
随着2019年1月,我想确认如何做到这一点,并提供一些额外的比特(有很多相互矛盾的信息在那里取决于答案写哪一年的!)。大卫和Waqas有最好的答案(IMO)。我使用MVC5,AspNetIdentity 2和3 IdentityServer。
首先,对于Facebook您的身份提供程序配置:
app.UseFacebookAuthentication(new FacebookAuthenticationOptions
{
AuthenticationType = "facebook",
Caption = "Login with Facebook",
SignInAsAuthenticationType = signInAsType,
AppId = ConfigurationManager.AppSettings["FacebookAppId"],
AppSecret = ConfigurationManager.AppSettings["FacebookAppSecret"],
Provider = new FacebookAuthenticationProvider()
{
OnAuthenticated = ctx =>
{
foreach (var claim in ctx.User)
{
var claimType = $"urn:facebook:{claim.Key}";
var claimValue = claim.Value.ToString();
if (!ctx.Identity.HasClaim(claim.Key, claimValue))
{
ctx.Identity.AddClaim(new Claim(claim.Key, claimValue));
}
}
return Task.FromResult(0);
}
}
});
不像一些其他的答案,这个结合了您在默认情况下会得到什么额外要求的领域,并采取urn:facebook:
关要求的前面,所以它默认的要求命名方案相匹配。
你不需要添加任何附加Scopes
或Fields
(至少,不是姓和名)。 Microsoft.Owin.Security.Facebook
的4.1版本已经这样做了你。该source code for the FacebookAuthenticationOptions is here。相关位:
public FacebookAuthenticationOptions()
: base(Constants.DefaultAuthenticationType)
{
Caption = Constants.DefaultAuthenticationType;
CallbackPath = new PathString("/signin-facebook");
AuthenticationMode = AuthenticationMode.Passive;
Scope = new List<string>();
BackchannelTimeout = TimeSpan.FromSeconds(60);
SendAppSecretProof = true;
_fields = new HashSet<string>();
CookieManager = new CookieManager();
AuthorizationEndpoint = Constants.AuthorizationEndpoint;
TokenEndpoint = Constants.TokenEndpoint;
UserInformationEndpoint = Constants.UserInformationEndpoint;
Scope.Add("public_profile");
Scope.Add("email");
Fields.Add("name");
Fields.Add("email");
Fields.Add("first_name");
Fields.Add("last_name");
}
如果您正在使用IdentityServer 3(像我),那么你就需要抓住身份验证这些说法在您的自定义UserService
像这样:
public async override Task AuthenticateExternalAsync(ExternalAuthenticationContext ctx)
{
// first, lets see if we have enough data from this external provider
// at a minimum, FirstName, LastName, and Email are required
string email = null;
string firstName = null;
string lastName = null;
var idp = ctx.ExternalIdentity.Provider;
email = GetClaimValue(ctx, "email");
if (idp == "google")
{
firstName = GetClaimValue(ctx, "given_name");
lastName = GetClaimValue(ctx, "family_name");
}
else if (idp == "facebook")
{
firstName = GetClaimValue(ctx, "first_name");
lastName = GetClaimValue(ctx, "last_name");
}
var missingClaims = "";
if (email == null)
{
missingClaims = "email";
}
if (firstName == null)
{
if (missingClaims.Length > 0) { missingClaims += ", "; }
missingClaims += "first name";
}
if (lastName == null)
{
if (missingClaims.Length > 0) { missingClaims += ", "; }
missingClaims += "last name";
}
if (missingClaims.Length > 0)
{
var errorMessage = $"The external login provider didn't provide the minimum required user profile data. Missing: {missingClaims} " +
"Verify that these fields are specified in your external login provider user profile and that you have allowed external apps (i.e. this one) access to them. " +
"Alternatively, you can try a different external login provider, or create a local acount right here.";
ctx.AuthenticateResult = new AuthenticateResult(errorMessage);
return;
}
var login = new Microsoft.AspNet.Identity.UserLoginInfo(ctx.ExternalIdentity.Provider, ctx.ExternalIdentity.ProviderId);
var user = await _userManager.FindAsync(login);
if (user == null)
{
// this user either does not exist or has not logged in with this identity provider
// let's see if they already exist (by checking to see if there is a user account with this email address)
user = await _userManager.FindByEmailAsync(email);
if (user == null)
{
// there is no existing user with this email, therefore, a new user will be created
user = new MotoTallyUser()
{
Id = Guid.NewGuid(),
UserName = email,
Email = email,
EmailConfirmed = true,
FirstName = firstName,
LastName = lastName
};
await _userManager.CreateAsync(user);
await _userManager.AddLoginAsync(user.Id, login);
}
else
{
// this user DOES exist (matched email provided by external login provider)
// however, they have not logged in with this identity provider
// therefore, update the user info with that reported by the external identity provider, and add the external login
user.UserName = email;
user.Email = email;
user.EmailConfirmed = true;
user.FirstName = firstName;
user.LastName = lastName;
await _userManager.UpdateAsync(user);
await _userManager.AddLoginAsync(user.Id, login);
}
}
else
{
// this user DOES exist (they already have an external login on record)
// therefore, update the user info with that reported by the external identity provider (no need to add external login, its already there)
user.UserName = email;
user.Email = email;
user.EmailConfirmed = true;
user.FirstName = firstName;
user.LastName = lastName;
await _userManager.UpdateAsync(user);
}
ctx.AuthenticateResult = new AuthenticateResult(user.Id.ToString(), user.Email, null, ctx.ExternalIdentity.Provider);
return;
}
private string GetClaimValue(ExternalAuthenticationContext ctx, string claimType)
{
if (ctx.ExternalIdentity.Claims.FirstOrDefault(x => x.Type == claimType) != null)
{
return ctx.ExternalIdentity.Claims.FirstOrDefault(x => x.Type == claimType).Value;
}
return null;
}
希望这可以帮助别人!
Facebook已经改变了他们的图形API返回值升级2.4。现在,你需要明确指定所有你想回去的字段。
查看从此注:facebook for developers Upgrade Info:
在2.4版本的图形API的变化
在过去,从图形API调用的响应返回一组默认的字段。为了减少有效载荷的大小和改善延迟对移动网络,我们已经减少返回大多数图形API调用默认的字段数。在V2.4则需要声明列出响应字段您的来电。
为了从Facebook获取电子邮件,名字和姓氏:
首先,您需要安装Facebook SDK for .NET NuGet包
然后,在你startup.Auth.cs,改变Facebook的身份验证如下配置:
app.UseFacebookAuthentication(new FacebookAuthenticationOptions
{
// put your AppId and AppSecret here. I am reading them from AppSettings
AppId = ConfigurationManager.AppSettings["FacebookAppId"],
AppSecret = ConfigurationManager.AppSettings["FacebookAppSecret"],
Scope = { "email" },
Provider = new FacebookAuthenticationProvider
{
OnAuthenticated = context =>
{
context.Identity.AddClaim(new System.Security.Claims.Claim("FacebookAccessToken", context.AccessToken));
return Task.FromResult(true);
}
}
});
// this is no longer needed
//app.UseFacebookAuthentication(
// appId: ConfigurationManager.AppSettings["FacebookAppId"],
// appSecret: ConfigurationManager.AppSettings["FacebookAppSecret"]);
最后,在你的AccountController,添加以下代码ExternalLoginCallback方法:
if (string.Equals(loginInfo.Login.LoginProvider, "facebook", StringComparison.CurrentCultureIgnoreCase))
{
var identity = AuthenticationManager.GetExternalIdentity(DefaultAuthenticationTypes.ExternalCookie);
var access_token = identity.FindFirstValue("FacebookAccessToken");
var fb = new FacebookClient(access_token);
// you need to specify all the fields that you want to get back
dynamic myInfo = fb.Get("/me?fields=email,first_name,last_name");
string email = myInfo.email;
string firstName = myInfo.first_name;
string lastName = myInfo.last_name;
}
见facebook API Guid更多的参数,你可以回去了。
在Facebook的选择范围添加名字和姓氏
var facebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions()
{
AppId = "your app id",
AppSecret = "your app secret",
};
facebookOptions.Scope.Add("email");
facebookOptions.Scope.Add("first_name");
facebookOptions.Scope.Add("last_name");
return facebookOptions;