2015-05-14 63 views
10

我不明白爲什麼他們不是一個明確的教程或指導,所以我希望我的問題可以在這裏得到解答。註冊外部登錄Web API

因此,試圖通過Web Api註冊Facebook或谷歌用戶。

的問題是,在RegisterExternal方法,在這條線:

var info = await Authentication.GetExternalLoginInfoAsync(); 

它返回null,從而返回BadRequest()

我得到了什麼至今:

Startup.Auth.cs我已經知道了身份證和祕密,請注意,我也試過使用Microsoft.Owin.Security.Facebook

var facebookOptions = new Microsoft.Owin.Security.Facebook.FacebookAuthenticationOptions 
      { 
       AppId = "103596246642104", 
       AppSecret = "1c9c8f696e47bbc661702821c5a8ae75", 
       Provider = new FacebookAuthenticationProvider() 
       { 
        OnAuthenticated = (context) => 
        { 
         context.Identity.AddClaim(new System.Security.Claims.Claim("urn:facebook:access_token", context.AccessToken, ClaimValueTypes.String, "Facebook")); 

         return Task.FromResult(0); 
        } 
       }, 
      }; 
      facebookOptions.Scope.Add("email"); 
      app.UseFacebookAuthentication(facebookOptions); 



      app.UseGoogleAuthentication(new GoogleOAuth2AuthenticationOptions() 
      { 
      ClientId = "328779658984-t9d67rh2nr681bahfusan0m5vuqeck13.apps.googleusercontent.com", 
      ClientSecret = "ZYcNHxBqH56Y0J2-tYowp9q0", 
      CallbackPath = new PathString("/api/Account/ManageInfo") 
     }); 

facebookOptions來源:this post

這額外facebookOptions沒有解決的問題。

我可以從Google和Facebook上檢索access_token。我也能與此的access_token來驗證api/Account/UserInfo

GET http://localhost:4856/api/Account/UserInfo 
in the header: 
Authorization: Bearer R9BTVhI0... 

將返回: {"Email":"firstname lastname","HasRegistered":false,"LoginProvider":"Facebook"}

一個問題,我注意到了,就是它返回我的名字是電子郵件,而不是實際的電子郵件地址。

現在我想爲我的數據庫中的新用戶,這是我做一個POST調用像這樣來註冊外部登錄:

POST http://localhost:4856/api/Account/RegisterExternal 
[header] 
authorization: bearer 6xcJoutY... 
Content-Type: application/json 
[body] 
{"Email":"[email protected]"} 

來源:this post

現在這個返回一個錯誤請求在此代碼片段,裏面RegisterExternal():

public async Task<ActionResult> ExternalLoginConfirmation(ExternalLoginConfirmationViewModel model, string returnUrl) 
    { 
if (!ModelState.IsValid) 
      { 
       return BadRequest(ModelState); 
      } 
      //AuthenticationManger? 
      var info = await Authentication.GetExternalLoginInfoAsync(); 
      if (info == null) 
      { 
       return InternalServerError(); 
      } 

在調試時,ExternalLoginConfirmationViewModel確實包含我的電子郵件地址。

我在做什麼錯?我需要在Startup.cs上添加什麼嗎? Startup.Auth.cs還有什麼我需要做的嗎?我錯誤地打電話給RegisterExternal嗎?在MVC中它非常流暢,爲什麼不在Web API中?

阿蘇看着this answerthis question,但我不明白如何實現這一點。

+0

當時這個不斷解決?我有同樣的問題。 –

+2

最後,我在應用程序端使用了Facebook進行身份驗證,就像在開發應用程序時一樣。然後使用外部訪問令牌在我的API上註冊我的用戶。遵循本教程:http://bitoftech.net/2014/08/11/asp-net-web-api-2-external-logins-social-logins-facebook-google-angularjs-app/如果您有第四個外部訪問令牌,您可以使用它來使用facebook圖表API獲取用戶信息。這是在android的這個答案:http://stackoverflow.com/questions/31314124/get-email-and-name-facebook-sdk-v4-4-0-swift – CularBytes

+0

非常感謝,非常有幫助。 –

回答

4

這種方法並不實際,因爲您正在開發一個API,它很可能會用於應用程序,您最好的方法是通過API消費者處理Facebook的登錄,並讓他們發送給您facebook認證令牌。

基本上我試圖做到這一點:

  1. 創建外部登錄鏈接爲Facebook。
  2. 發送用戶到該鏈接,將他們帶到Facebook的登錄頁面。
  3. 登錄後facebook將重定向到api。
  4. 用戶將被註冊,但消費API的應用/網站是如何知道的?

你想要做的是這樣的:

  1. API使用者創建他們自己的方法與Facebook登錄(通過SDK的應用程序)
  2. API的消費者將發送一個Facebook的令牌API來註冊/登錄。
  3. API將檢查令牌與facebook圖形端點。
  4. 成功時,API將返回一個不記名令牌讓API進一步驗證請求。

所以你作爲一個API開發人員,你會驗證令牌就像這樣:

var verifyTokenEndPoint = string.Format("https://graph.facebook.com/debug_token?input_token={0}&access_token={1}", accessToken, appToken); 

然後獲取用戶標識

var client = new HttpClient(); 
var uri = new Uri(verifyTokenEndPoint); 
var response = await client.GetAsync(uri); 

if (response.IsSuccessStatusCode) 
{ 
    var content = await response.Content.ReadAsStringAsync(); 

    dynamic jObj = (JObject)Newtonsoft.Json.JsonConvert.DeserializeObject(content); 

    string user_id = jObj["data"]["user_id"]; 
    string app_id = jObj["data"]["app_id"]; 
} 

最終,你將創建或找到像用戶所以:

IdentityUser user = await _userManager.FindAsync(new UserLoginInfo(provider, verifiedAccessToken.user_id)); 

然後這一切都取決於你如何c reate一個承載的道理,如果你按照下面列出的教程,你可以有這樣的:

var tokenExpiration = TimeSpan.FromMinutes(30); 

ClaimsIdentity identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType); 

identity.AddClaim(new Claim(ClaimTypes.Name, userName)); 
identity.AddClaim(new Claim("role", "user")); 

var props = new AuthenticationProperties() 
{ 
    IssuedUtc = DateTime.UtcNow, 
    ExpiresUtc = DateTime.UtcNow.Add(tokenExpiration), 
}; 

var ticket = new AuthenticationTicket(identity, props); 

var accessToken = Startup.OAuthBearerOptions.AccessTokenFormat.Protect(ticket); 

源,採用全教程here

我也通過SDK得到了電子郵件,然後發送與沿POST請求,因爲我管理API和消費者。警告雖然:Facebook用戶可能不想給你一個電子郵件地址。

獲取Facebook登錄後電子郵件上AndroidIOS