Dav*_*xon 8 facebook ios asp.net-web-api owin asp.net-web-api2
我做了很多搜索,但却找不到理想的解决方案.我知道有一个所谓的解决方案(WebApi ASP.NET身份Facebook登录)但是,解决方案的一些元素是(在我看来)严重hacky(例如,用普通帐户注册用户,然后添加外部登录,而不是而不是使用外部登录注册它们).
我希望能够在已经在iOS移动应用程序上使用Facebook SDK登录后注册和验证ASP.NET Web API 2应用程序,即我已经使用他们的SDK对Facebook进行了身份验证,现在想要无缝地使用ASP.NET Web API注册/验证.我不想使用我必须使用Web调用(/ api/Account/ExternalLogin)的过程,因为这对本机移动应用程序来说不是一个很好的用户体验.
我试过学习OWIN,但.NET框架很复杂,我在如何解决这个问题上一直在努力.
我今天需要为我的 Ionic 应用程序执行此操作。Web API 帐户控制器对于如何做事有自己的看法,理解它的最佳方法是阅读 Dominick Baier 撰写的这篇非常精彩的 3 部分博客文章。https://leastprivilege.com/2013/11/26/dissecting-the-web-api-individual-accounts-templatepart-3-external-accounts/。
我解决这个问题的方法是忘记开箱即用的流程,而是使用本机 Facebook 登录中的 accessToken,然后调用以下服务器代码来 1) 调用 Facebook API 来验证访问令牌, 2) 从 Facebook 调用中获取电子邮件和 ID,3) 获取用户或创建用户(并登录),这已经是其他地方帐户控制器中的代码,4) 为后续 Web API 创建本地权限 JWT来电。
public class ProviderAndAccessToken {
public string Token { get; set; }
public string Provider { get; set; }
}
[AllowAnonymous]
[HttpPost]
[Route("JwtFromProviderAccessToken")]
public async Task<IHttpActionResult> JwtFromProviderAccessToken(ProviderAndAccessToken model) {
string id = null;
string userName = null;
if (model.Provider == "Facebook") {
var fbclient = new Facebook.FacebookClient(model.Token);
dynamic fb = fbclient.Get("/me?locale=en_US&fields=name,email");
id = fb.id;
userName = fb.email;
}
//TODO: Google, LinkedIn
ApplicationUser user = await UserManager.FindAsync(new UserLoginInfo(model.Provider, id));
bool hasRegistered = user != null;
string accessToken = null;
var identity = new ClaimsIdentity(OAuthDefaults.AuthenticationType);
var props = new AuthenticationProperties() {
IssuedUtc = DateTime.UtcNow,
ExpiresUtc = DateTime.UtcNow.Add(Startup.OAuthOptions.AccessTokenExpireTimeSpan),
};
if (hasRegistered) {
ClaimsIdentity oAuthIdentity = await user.GenerateUserIdentityAsync(UserManager,
OAuthDefaults.AuthenticationType);
ClaimsIdentity cookieIdentity = await user.GenerateUserIdentityAsync(UserManager,
CookieAuthenticationDefaults.AuthenticationType);
AuthenticationProperties properties = ApplicationOAuthProvider.CreateProperties(user.UserName);
Authentication.SignIn(properties, oAuthIdentity, cookieIdentity);
identity.AddClaim(new Claim(ClaimTypes.Name, user.UserName));
identity.AddClaim(new Claim("role", "user"));
}
else {
user = new ApplicationUser() { UserName = userName, Email = userName };
IdentityResult result = await UserManager.CreateAsync(user);
if (!result.Succeeded) {
return GetErrorResult(result);
}
result = await UserManager.AddLoginAsync(user.Id, new UserLoginInfo(model.Provider, id));
if (!result.Succeeded) {
return GetErrorResult(result);
}
identity.AddClaim(new Claim(ClaimTypes.Name, userName));
}
identity.AddClaim(new Claim("role", "user"));
var ticket = new AuthenticationTicket(identity, props);
accessToken = Startup.OAuthOptions.AccessTokenFormat.Protect(ticket);
return Ok(accessToken);
}
Run Code Online (Sandbox Code Playgroud)
我在 Ionic 中使用的代码基本上是从 Facebook 获取访问令牌,然后调用 Web API 获取本地权限 JWT 以用作承载令牌。
Facebook.login(['public_profile', 'email']).then((result) => {
return this.http.post("<URL>/api/Account/JwtFromProviderAccessToken", { provider: "Facebook", token: result.authResponse.accessToken })
.map((res: Response) => res.json())
.catch(this.handleError)
.subscribe((res: Response) => {
// use the result as the Bearer token
});
})...
Run Code Online (Sandbox Code Playgroud)
看起来很安全,但请注意,我不是安全专家,因此此代码没有保修,如果您发现任何明显的问题,请告诉我,我会更新代码。
| 归档时间: |
|
| 查看次数: |
1262 次 |
| 最近记录: |