2013-01-10 60 views
2

使用Microsoft.AspNet.Membership.OpenAuth我很快就能通過各種外部提供商(臉譜,微博,谷歌,微軟)獲得一個應用程序登錄人。那很棒。通過ASP.NET Membership.OpenAuth獲取用戶個人資料信息

我的問題是,我可以使用此框架輕鬆獲取用戶配置文件信息嗎?如果服務有它們,我想獲得他們的個人資料照片,電子郵件地址,DOB等。

我知道AuthenticationResult.ExtraData中有一些額外的信息,但它不是標準的,也不包含我所需要的。

有什麼我可以從這裏得到的信息使用Microsoft.AspNet.Membership.OpenAuth(或另一個.net lib)或我需要使用ExtraData中的訪問令牌來通過手動訪問不同的服務單獨的服務API?

感謝

+0

+1好問題,但我有預感,這主要取決於應用程序如何設置在每個提供程序。例如,如果您告訴Facebook您的應用程序應該請求訪問聯繫人,圖片,電子郵件等,那麼當用戶重定向到Facebook的登錄頁面時,他應該特別授予您對所有這些信息的訪問權限。一旦你的網站被回電,很可能你所有的信息都可以訪問到......這只是我的猜測,我有興趣看到一些答案。 – Icarus

+0

我認爲你需要註冊你的網站與某些外部供應商,如Facebook之前,你可以訪問到用戶的Facebook配置文件數據。 – Derek

+0

您需要向大多數(如果不是全部的話)提供者進行註冊,甚至可以記錄使用OpenAuth庫的人員。 – radm4

回答

0

驗證工作流程有兩個主要問題需要解決。其一,正如OP正確指出的那樣,涉及ExtraData的內容,另一個涉及您需要向Facebook提供的權限。最後,我去了DotNetOpenAuth圖書館,而不是微軟的圖書館,但在某些地方擴展了它,通過滾動我自己的課程並在必要時借用框架的一部分。

我做的第一件事是創建一個FacebookClient即延長從DotNetOpenAuthOAuth2Client,讓我在一個值傳遞爲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調用。序列化類看起來是這樣的:每@ radm4

[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; } 
} 

當我還是檢查提供的字符串來決定在某些地方要調用哪些方法 - 一個更優雅的解決方案是一個仍在工作......

+0

謝謝水平, 這基本上是我得出的結論,你的解決方案是很好的,因爲它擴展了已有的東西,我想我會嘗試採用這種方式來做。 – radm4

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可以登錄並且非常基本的信息,但是如果你需要更多的信息,你需要擴展或者傳遞給每個提供者。

+0

對於任何人想知道,因爲我已經收集了最好的谷歌API的這個功能是http://code.google.com/p/google-api-dotnet-client/wiki/OAuth2和其他API的工作它是如谷歌+等 – radm4

相關問題