2

Microsoft.AspNet.Membership.OpenAuth を使用して、さまざまな外部プロバイダー (facebook、twitter、google、microsoft) を介してユーザーをログインさせるアプリをすぐに取得できました。それは素晴らしいことです。

私の質問は、このフレームワークを使用してユーザーのプロファイル情報を簡単に取得できるかということです。サービスにあれば、プロフィール写真、メールアドレス、生年月日などを取得したいと思います。

AuthenticationResult.ExtraData に追加情報があることは知っていますが、それは標準ではなく、必要なものが含まれていません。

Microsoft.AspNet.Membership.OpenAuth (または別の .net lib) を使用して情報を取得するためにここからできることはありますか?それとも、ExtraData のアクセス トークンを使用して、個別のサービス API を介して手動でさまざまなサービスにアクセスする必要がありますか?

ありがとう

4

2 に答える 2

0

認証ワークフローに関するもので克服すべき2つの主要な問題があります。1つは、OPが正しく指摘したように、コンテンツに関するものでExtraDataあり、もう1つは、Facebookに要求する必要のある権限に関するものです。結局、私はDotNetOpenAuthMicrosoftのライブラリではなくライブラリを使用しましたが、必要に応じて独自のクラスをローリングし、フレームワークの一部を借用することで、特定の場所でライブラリを拡張しました。

私が最初にしたことは、 fromFacebookClientを拡張し、の値を渡すことができるaを作成することでした。これにより、Facebookに要求できるデータの制限を超えました。私が求める許可はです。それらは単にサービスのログインURLに追加され、Facebookに渡されます。私の実装内の便利な方法は次のとおりです。OAuth2ClientDotNetOpenAuthscopepublish_stream, manage_pages, email, user_interestsOAuth2ClientGetUserData

    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のとおり、プロバイダー文字列をチェックして、特定の場所で呼び出すメソッドを決定します。それでも、そのメソッドに対するより洗練されたソリューションに取り組んでいます...

于 2013-01-11T13:46:27.727 に答える
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 を使用してこの追加情報にアクセスできます。

Google にもこのタイプのものを追加する予定です。ユーザーが他のサービスを使用してログインしたい場合は、ログインできますが、asp.net oauth を使用するだけで、各プロバイダーに費やす時間が増えるまで、facebook や google のようにカスタマイズされたエクスペリエンスを得ることができません。

したがって、基本的に答えは、ASP.net oauth はログインと非常に基本的な情報には問題ありませんが、さらに必要な場合は、プロバイダーごとに拡張またはバイパスする必要があります。

于 2013-01-11T12:36:46.413 に答える