認証ワークフローに関するもので克服すべき2つの主要な問題があります。1つは、OPが正しく指摘したように、コンテンツに関するものでExtraData
あり、もう1つは、Facebookに要求する必要のある権限に関するものです。結局、私はDotNetOpenAuth
Microsoftのライブラリではなくライブラリを使用しましたが、必要に応じて独自のクラスをローリングし、フレームワークの一部を借用することで、特定の場所でライブラリを拡張しました。
私が最初にしたことは、 fromFacebookClient
を拡張し、の値を渡すことができるaを作成することでした。これにより、Facebookに要求できるデータの制限を超えました。私が求める許可はです。それらは単にサービスのログインURLに追加され、Facebookに渡されます。私の実装内の便利な方法は次のとおりです。OAuth2Client
DotNetOpenAuth
scope
publish_stream, manage_pages, email, user_interests
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から応答が返ってきたときに逆シリアル化されるデータクラスをいくつか作成しました。ここから、必要な他のGraphAPI呼び出しを行うこともできます。シリアル化クラスは次のようになります。
[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のとおり、プロバイダー文字列をチェックして、特定の場所で呼び出すメソッドを決定します。それでも、そのメソッドに対するより洗練されたソリューションに取り組んでいます...