使用Microsoft.AspNet.Membership.OpenAuth我很快就能通过各种外部提供商(facebook,twitter,google,microsoft)获取应用程序。那很好。
我的问题是,我可以使用此框架轻松获取用户个人资料信息吗?如果服务有,我想获取他们的个人资料图片,电子邮件地址,DOB等。
我知道AuthenticationResult.ExtraData中有一些额外的信息,但它不是标准的,不包含我需要的内容。
我可以从这里使用Microsoft.AspNet.Membership.OpenAuth(或其他.net lib)获取信息,或者我需要使用ExtraData中的访问令牌通过单独的手动访问不同的服务服务API?
由于
答案 0 :(得分:0)
环顾四周之后,我无法通过Microsoft.AspNet.Membership.OpenAuth的东西看到这样做的方法。
如果用户想要使用Facebook,我的解决方案就是跳过.NET oauth的东西。在这种情况下,我使用facebook C#SDK进行身份验证,然后我可以访问电子邮件,生日,照片等。
if(provider != "facebook")
{
//do normal oauth
}
else
{
FacebookClient client = new FacebookClient();
var loginUrl = client.GetLoginUrl(new
{
client_id = ConfigurationManager.AppSettings["facebookId"],
client_secret = ConfigurationManager.AppSettings["facebookClientSecret"],
redirect_uri = redirectUrl,
response_type = "code",
scope = "email,user_birthday"
});
Response.Redirect(loginUrl.AbsoluteUri);
}
当用户返回时,您可以使用SDK访问此额外信息。
我也要为谷歌添加这类东西。如果用户想要使用其他服务登录他们可以,但我只会使用asp.net oauth,他们不会像facebook或google那样获得定制体验,直到我有更多时间花在每个提供商上。
所以基本上答案是ASP.net oauth适合登录和非常基本的信息,但是如果你需要更多,你需要扩展或传递给每个提供商。
答案 1 :(得分:0)
验证工作流程有两个主要问题需要解决。一,正如OP正确指出的那样涉及ExtraData
的内容,另一个涉及您需要向Facebook询问的权限。最后,我使用DotNetOpenAuth
库而不是Microsoft库,但是通过滚动我自己的类并在必要时借用框架的一部分,在某些地方扩展它。
我做的第一件事是创建一个FacebookClient
,将OAuth2Client
扩展为DotNetOpenAuth
并允许我传递scope
的值,该值超出了限制您可以从Facebook请求哪些数据。我要求的许可是publish_stream, manage_pages, email, user_interests
。它们只是附加到服务登录URL并传递到Facebook。我OAuth2Client
实施中的有用方法是GetUserData
:
protected override IDictionary<string, string> GetUserData(string accessToken)
{
var token = accessToken.EscapeUriDataStringRfc3986();
FacebookGraphData graphData;
var request = WebRequest.Create(string.Format("https://graph.facebook.com/me?access_token={0}", token));
using (var response = request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
graphData = JsonHelper.Deserialize<FacebookGraphData>(responseStream);
}
}
var userData = new Dictionary<string, string> {{"accessToken", accessToken}};
userData.AddItemIfNotEmpty("id", graphData.Id);
userData.AddItemIfNotEmpty("name", graphData.Name);
userData.AddItemIfNotEmpty("email", graphData.Email);
userData.AddItemIfNotEmpty("firstName", graphData.FirstName);
userData.AddItemIfNotEmpty("lastName", graphData.LastName);
userData.AddItemIfNotEmpty("link", graphData.Link == null ? null : graphData.Link.AbsoluteUri);
userData.AddItemIfNotEmpty("username", graphData.Username);
userData.AddItemIfNotEmpty("gender", graphData.Gender);
userData.AddItemIfNotEmpty("locale", graphData.Locale);
FacebookFriendData friendData;
request = WebRequest.Create(string.Format("https://graph.facebook.com/me/friends?access_token={0}", token));
using (var response = request.GetResponse())
{
using (var responseStream = response.GetResponseStream())
{
friendData = JsonHelper.Deserialize<FacebookFriendData>(responseStream);
}
}
if (friendData.Friends != null)
{
userData.Add("connections", friendData.Friends.Count().ToString());
}
return userData;
}
我基本上创建了一些数据类,当响应从Facebook返回时,这些数据类被反序列化。我还可以从这里进行任何其他我需要的Graph API调用。序列化类看起来像这样:
[DataContract]
public class FacebookFriendData
{
[DataMember(Name = "data")]
public IEnumerable<Friend> Friends { get; set; }
}
[DataContract]
public class Friend
{
[DataMember(Name = "id")]
public string Id { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
}
[DataContract]
public class FacebookGraphData
{
[DataMember(Name = "id")]
public string Id { get; set; }
[DataMember(Name = "name")]
public string Name { get; set; }
[DataMember(Name = "email")]
public string Email { get; set; }
[DataMember(Name = "first_name")]
public string FirstName { get; set; }
[DataMember(Name = "last_name")]
public string LastName { get; set; }
[DataMember(Name = "link")]
public Uri Link { get; set; }
[DataMember(Name = "username")]
public string Username { get; set; }
[DataMember(Name = "gender")]
public string Gender { get; set; }
[DataMember(Name = "locale")]
public string Locale { get; set; }
}
根据@radm4,我仍然检查提供程序字符串以决定在某些地方调用哪些方法 - 仍在为这个方法提供更优雅的解决方案......