我不確定這是否是正確的方式來做到這一點,但我的實施工作。
的工作流,
- iOS應用使用Facebook SDK
- iOS應用使用Facebook訪問令牌
- .NET創建在.NET後端用戶得到一個Facebook訪問令牌後端驗證Facebook訪問令牌是否有效並下載用戶數據
- .NET後端創建一個jwt載體令牌並將其返回給iOS應用程序
- iOS應用程序使用jwt載體toke調用.NET後端N的授權HTTP標題
我檢查了Facebook訪問令牌是有效的,通過調用https://graph.facebook.com - 是指:任務VerifyAccessToken(字符串email,字符串的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));
}
}
調用Facebook的圖表服務,以驗證訪問令牌是有效的
public async Task<FacebookMeResponse> VerifyAccessToken(string email, string accessToken)
{
if (string.IsNullOrEmpty(accessToken))
{
throw new ValidationException("Invalid Facebook token");
}
string facebookGraphUrl = "https://graph.facebook.com/me?fields=cover,age_range,first_name,location,last_name,hometown,gender,birthday,email&access_token=" + accessToken;
WebRequest request = WebRequest.Create(facebookGraphUrl);
request.Credentials = CredentialCache.DefaultCredentials;
using (WebResponse response = await request.GetResponseAsync())
{
var status = ((HttpWebResponse)response).StatusCode;
Stream dataStream = response.GetResponseStream();
StreamReader reader = new StreamReader(dataStream);
string responseFromServer = reader.ReadToEnd();
var facebookUser = JsonConvert.DeserializeObject<FacebookMeResponse>(responseFromServer);
bool valid = facebookUser != null && !string.IsNullOrWhiteSpace(facebookUser.Email) && facebookUser.Email.ToLower() == email.ToLower();
facebookUser.PublicProfilePhotoUrl = "http://graph.facebook.com/" + facebookUser.Id + "/picture";
if (!valid)
{
throw new ValidationException("Invalid Facebook token");
}
return facebookUser;
}
}
爲您的中間件創建一個jwt記載令牌,iOS應用將使用jwt記載令牌來調用您的中間件。NET的API(它不會使用Facebook的access_token)
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);
}
創建一個用戶,如果它不存在
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);
}
類的去連載從Facebook的圖形REST服務響應
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;
}
}
請回復您的答案...其他人(如我)可能會受益T hanks – Stephane
@Stephane,完成!對於慢響應抱歉。你是如何繼續實施的?我想和你的朋友進行比較 – ProgrammerGuy