2015-05-14 60 views
10

我不明白为什么他们不是一个明确的教程或指导,所以我希望我的问题可以在这里得到解答。注册外部登录Web API

因此,试图通过Web Api注册Facebook或谷歌用户。

的问题是,在RegisterExternal方法,在这条线:

var info = await Authentication.GetExternalLoginInfoAsync(); 

它返回null,从而返回BadRequest()

我得到了什么至今:

Startup.Auth.cs我已经知道了身份证和秘密,请注意,我也试过使用Microsoft.Owin.Security.Facebook

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

这额外facebookOptions没有解决的问题。

我可以从Google和Facebook上检索access_token。我也能与此的access_token来验证api/Account/UserInfo

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

将返回: {"Email":"firstname lastname","HasRegistered":false,"LoginProvider":"Facebook"}

一个问题,我注意到了,就是它返回我的名字是电子邮件,而不是实际的电子邮件地址。

现在我想为我的数据库中的新用户,这是我做一个POST调用像这样来注册外部登录:

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

来源:this post

现在这个返回一个错误请求在此代码片段,里面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(); 
      } 

在调试时,ExternalLoginConfirmationViewModel确实包含我的电子邮件地址。

我在做什么错?我需要在Startup.cs上添加什么吗? Startup.Auth.cs还有什么我需要做的吗?我错误地打电话给RegisterExternal吗?在MVC中它非常流畅,为什么不在Web API中?

阿苏看着this answerthis question,但我不明白如何实现这一点。

+0

当时这个不断解决?我有同样的问题。 –

+2

最后,我在应用程序端使用了Facebook进行身份验证,就像在开发应用程序时一样。然后使用外部访问令牌在我的API上注册我的用户。遵循本教程:http://bitoftech.net/2014/08/11/asp-net-web-api-2-external-logins-social-logins-facebook-google-angularjs-app/如果您有第四个外部访问令牌,您可以使用它来使用facebook图表API获取用户信息。这是在android的这个答案:http://stackoverflow.com/questions/31314124/get-email-and-name-facebook-sdk-v4-4-0-swift – CularBytes

+0

非常感谢,非常有帮助。 –

回答

4

这种方法并不实际,因为您正在开发一个API,它很可能会用于应用程序,您最好的方法是通过API消费者处理Facebook的登录,并让他们发送给您facebook认证令牌。

基本上我试图做到这一点:

  1. 创建外部登录链接为Facebook。
  2. 发送用户到该链接,将他们带到Facebook的登录页面。
  3. 登录后facebook将重定向到api。
  4. 用户将被注册,但消费API的应用/网站是如何知道的?

你想要做的是这样的:

  1. API使用者创建他们自己的方法与Facebook登录(通过SDK的应用程序)
  2. API的消费者将发送一个Facebook的令牌API来注册/登录。
  3. API将检查令牌与facebook图形端点。
  4. 成功时,API将返回一个不记名令牌让API进一步验证请求。

所以你作为一个API开发人员,你会验证令牌就像这样:

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

然后获取用户标识

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

最终,你将创建或找到像用户所以:

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

然后这一切都取决于你如何c reate一个承载的道理,如果你按照下面列出的教程,你可以有这样的:

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

源,采用全教程here

我也通过SDK得到了电子邮件,然后发送与沿POST请求,因为我管理API和消费者。警告虽然:Facebook用户可能不想给你一个电子邮件地址。

获取Facebook登录后电子邮件上AndroidIOS