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;
}
}
Bitte posten Sie Ihre Antwort ... andere Leute (wie ich) könnten profitieren T hanks – Stephane
@Stephane, fertig! Entschuldigung für die langsame Antwort. Wie sind Sie bei Ihrer Implementierung vorgegangen? Ich möchte meine mit Ihrer vergleichen – ProgrammerGuy