2015-05-14 14 views
10

Nie rozumiem, dlaczego nie jest to jasny tutorial lub wytyczna na ten temat, więc mam nadzieję, że na moje pytanie można tu odpowiedzieć.Zarejestruj zewnętrzne logowanie Web API

Próbujesz zarejestrować użytkowników z Facebooka lub Google za pośrednictwem Web Api.

Problem polega na sposobie RegisterExternal, na tej linii:

var info = await Authentication.GetExternalLoginInfoAsync(); 

zwraca null, a tym samym zwracając BadRequest()

Co mam tak daleko:

W Startup.Auth.cs Posiadałem identyfikatory i sekrety, zauważ, że próbowałem również użyć Microsoft.Owin.Security.Facebook

0 źródło
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

że dodatkowe facebookOptions nie rozwiązuje problemu.

Jestem w stanie odzyskać hasło dostępu z Google i Facebooka. Jestem również w stanie uwierzytelnić się tym access_token do api/Account/UserInfo

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

która zwraca: {"Email":"firstname lastname","HasRegistered":false,"LoginProvider":"Facebook"}

Jeden problem zauważam ich, jest to, że zwraca moje nazwisko jako e-mail, a nie rzeczywisty adres e-mail.

Teraz chcę zarejestrować login zewnętrzne z nowego użytkownika do mojej bazy danych, którą wykonać połączenie POST takiego:

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

źródło: this post

Teraz zwraca BadRequest na ten temat Kod snippit, wewnątrz 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(); 
      } 

W debugowania The ExternalLoginConfirmationViewModel nie zawiera mój adres e-mail.

Co robię źle? Czy muszę coś dodać do Startup.cs? Czy jest coś więcej, co muszę zrobić w Startup.Auth.cs? Czy nieprawidłowo dzwonię pod numer RegisterExternal? W MVC idzie tak gładko, dlaczego nie w Web API?

Aso spojrzał na this answer z this question, ale nie rozumiem, jak to wdrożyć.

+0

Czy ta nigdy rozwiązany? Mam ten sam problem. –

+2

Ostatecznie dokonałem uwierzytelnienia na Facebooku po stronie App, tak jak powinno być przy tworzeniu aplikacji. Następnie za pomocą tokenu zewnętrznego dostępu zarejestrować moich użytkowników w moim interfejsie API. Po tym samouczku: http://bitoftech.net/2014/08/11/asp-net-web-api-2-external-logins-social-logins-facebook-google-angularjs-app/ Jeśli masz th zewnętrzny dostęp token, możesz go użyć do uzyskania informacji o użytkowniku za pomocą api facebook graph. Oto odpowiedź na to w android: http://stackoverflow.com/questions/31314124/get-email-and-name-facebook-sdk-v4-4-0-swift – CularBytes

+0

Dziękuję bardzo, bardzo pomocne. –

Odpowiedz

4

Ta metoda nie jest zbyt praktyczna, ponieważ opracowujesz interfejs API, który będzie najprawdopodobniej używany w aplikacjach. Najlepszym sposobem jest obsługa logowania za pomocą facebooka przez klienta API, a następnie wysłanie do niego wiadomości z Facebooka. znak.

Zasadniczo starałem się to zrobić:

  1. Tworzenie zewnętrznego linku logowania na Facebooku.
  2. Wyślij użytkownika do tego linku, który przeniesie go na stronę logowania na Facebooku.
  3. Po zalogowaniu facebook przekieruje do api.
  4. Użytkownik byłby zarejestrowany, ale w jaki sposób znana jest aplikacja/witryna, która pobiera interfejs API?

Co chcesz zrobić to:

  1. API konsument tworzy swój własny sposób, aby zalogować się z Facebook (dla aplikacji za pośrednictwem SDK)
  2. API konsument wyśle ​​facebook token do API zarejestruj się/zaloguj.
  3. API sprawdzi token z punktem końcowym na Facebooku.
  4. Po pomyślnym zakończeniu API zwróci token na okaziciela dla interfejsu API w celu wykonania kolejnych uwierzytelnionych żądań.

Więc dla ciebie jako programisty API, by zweryfikować tokenu tak:

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

a następnie uzyskać identyfikator użytkownika

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"]; 
} 

Ostatecznie można utworzyć lub znaleźć użytkownika jak więc:

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

A teraz wszystko zależy od ciebie Reate się okaziciela żeton, jeśli się tutorial wymienionych poniżej, można mieć to:

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); 

źródło, z pełnym tutorialu here

Mam również za pośrednictwem wiadomości e-mail i wysłać SDK, które wraz z żądanie POST, ponieważ zarządzałem zarówno API, jak i konsumentem. Ostrzeżenie: Użytkownik Facebooka może nie chcieć podać adresu e-mail.

Get e-mail po zalogowaniu się na facebook Android i IOS