2016-08-14 3 views
2

Ich implementiere Facebook Logins auf einer iOS App mit einem .net Core Web API Backend.Kann ich ein Facebook jwt-Token überprüfen, das mit nativem iOS-SDK mit einem .net-Backend erstellt wurde?

  1. Ich habe die App in Facebook mit einer Client-ID und einem geheimen erstellt.
  2. Ich fügte hinzu, iOS und Web-Seiten zu meiner app
  3. Die iOS-App verbindet erfolgreich und erwirbt ein Token
  4. ich den app.UseFacebook Code meiner startup.cs hinzugefügt und konfiguriert es mit der App-ID usw.
  5. ich habe das Autorisieren Attribut zu einer Aktion, die ich Zugang zu beschränken bin zu
  6. ich diese Web-api Aktion von iOS rufen mit einem https get, und fügen Sie einen hTTP-Header Authorization Bearer (Token ich von Facebook erworben)

Der Abrufstatus wird zurückgegeben Code 401, als ob mein Token ungültig wäre. Ich frage mich, ob iOS-Tokens auch mit einer Webseiten-App verwendet werden können? Ich habe diese 2 für meine Facebook App konfiguriert.

+0

Bitte posten Sie Ihre Antwort ... andere Leute (wie ich) könnten profitieren T hanks – Stephane

+0

@Stephane, fertig! Entschuldigung für die langsame Antwort. Wie sind Sie bei Ihrer Implementierung vorgegangen? Ich möchte meine mit Ihrer vergleichen – ProgrammerGuy

Antwort

1

ASP.NET Security repo enthält verschiedene Auth-Middlewares, wo Sie finden können, wie Sie JWT-Token überprüfen und überprüfen und Identität mit Ansprüchen erstellen. Schauen Sie in FacebookHandler.cs, wenn Sie Facebook JWT tönen Validierung benötigen

+0

Ich benutze bereits diese Bibliotheken, aber Sie haben mir die Idee gegeben, den Quellcode des .net-Frameworks in mein Debugging aufzunehmen, um zu sehen, was unter der Haube passiert und welche Eigenschaften sich ergeben es durch die Schichten und welche Methoden werden aufgerufen und warum. Vielen Dank! – ProgrammerGuy

+0

Links sind unterbrochen – Softlion

+0

@Softlion behoben. Sie verwenden jetzt 'dev'-Branchenname anstelle von' master' (falls Sie irgendwelche anderen gebrochenen Links finden, kann es das gleiche Problem sein) – Set

5

Ich bin nicht sicher, ob dies der richtige Weg war, es zu tun, aber meine Implementierung funktioniert.

Der Workflow ist,

  • iOS-App ein Token Facebook Zugangs bekommt einen Benutzer in dem .NET-Back-End des Facebook-sdk
  • iOS-App mit dem Token Facebook Zugang erstellt
  • .NET Backend prüft, ob das Facebook Access Token gültig ist und lädt Benutzerdaten herunter
  • .NET Backend erstellt ein JWT Bearer Token und gibt es an die iOS App zurück
  • iOS App ruft .NET Backend mit dem JWT Bearer Toke auf n in der Autorisierungs-HTTP-Header

prüfe ich die Facebook-Zugriffstoken https://graph.facebook.com durch den Aufruf gültig ist - siehe: Aufgabe VerifyAccessToken (string E-Mail, string accessToken)

AccountController.cs

[AllowAnonymous, HttpPost("[action]")] 
public async Task<ActionResult> FacebookAuth([FromBody] ExternalLoginModel model) 
{ 
    try 
    { 
     await _interactor.VerifyAccessToken(model.Email, model.Token); 

     var result = await _interactor.SignInWithFacebook(model.Email); 

     return Ok(result);    
    } 
    catch (ValidationException ex) 
    { 
     return BadRequest(ex.Message.ErrorMessage(Strings.ValidationException)); 
    } 
} 

[AllowAnonymous, HttpPost("[action]")] 
public async Task<ActionResult> CreateAccountWithFacebook(AccountModel account, string token) 
{ 
    try 
    { 
    await _interactor.VerifyAccessToken(account.Email, token); 

    if (ModelState.IsValid) 
    {    
     var result = await _interactor.CreateFacebookLogin(account); 

     return Ok(result); 
    } 

    return BadRequest(ModelState); 
    } 
    catch (ValidationException ex) 
    { 
    return BadRequest(ex.Message.ErrorMessage(Strings.ValidationException)); 
    } 
} 

Rufen Sie den facebook graph service an, um zu überprüfen, ob der Zugriffstoken gültig ist

Erstellen Sie ein JWT-Bearer-Token für Ihre Middleware, die iOS-App verwendet das JWT-Bearer-Token zum Aufrufen Ihres.NET apis (es wird nicht die Facebook access_token verwenden)

public async Task<FacebookResponse> SignInWithFacebook(string email) 
{ 
    var claims = new List<Claim>(); 

    var user = await _userManager.FindByEmailAsync(email); 

    var identity = new ClaimsIdentity(claims, "oidc"); 

    var jwtBearerToken= Guid.NewGuid().ToString(); 
    var properties = new AuthenticationProperties(); 
    properties.Items.Add(".Token.access_token", jwtBearerToken); 

    await _signInManager.SignInAsync(user, properties, "oidc"); 

    var principal = await _signInManager.CreateUserPrincipalAsync(user); 

    var token = new Token(); 
    token.Key = jwtBearerToken; 
    token.Expiry = DateTime.UtcNow.AddMinutes(30); 
    token.UserId = user.Id; 
    token.TokenType = "FacebookLogin"; 

    await _tokensRepository.Save(token); 
    var result = _signInManager.IsSignedIn(principal); 

    return new FacebookResponse("success", result, jwtBearerToken); 
} 

einen Benutzer erstellen, wenn es existieren tut

public async Task<FacebookResponse> CreateFacebookLogin(AccountModel model) 
{ 
    User user = await _userManager.FindByEmailAsync(model.Email); 

    if (user == null) 
    { 
     var createResult = await _userManager.CreateAsync(_mapper.Map<AccountModel, User>(model)); 
     if (!createResult.Succeeded) 
     { 
      // handle failure.. 
     }     
    } 

    return await SignInWithFacebook(model.Email); 
} 

Klassen für de-Serialisierung die Antwort von dem Facebook Graph REST-Service

public class FacebookAgeRange 
{ 
    public int Min { get; set; } 
} 

public class FacebookMeResponse 
{ 
    public string Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public string Email { get; set; } 
    public string Gender { get; set; } 
    public FacebookAgeRange AgeRange { get; set; } 
    public string PublicProfilePhotoUrl { get; set; } 
} 

public class FacebookResponse : IResponse 
{ 
    public bool Ok { get; set; } 
    public string Message { get; set; } 
    public string JwtToken { get; set; } 

    public FacebookResponse(string message, bool ok = true, string jwtToken = "") 
    { 
     this.Message = message; 
     this.Ok = ok; 
     this.JwtToken = jwtToken; 
    } 
} 
Verwandte Themen