注册外部登录Web API



我不明白为什么他们的教程不是一个明确的教程或指南,所以我希望我的问题可以在这里回答。

因此,尝试通过Web API从Facebook或Google注册用户。

问题是在RegisterExternal方法上,在此行:

var info = await Authentication.GetExternalLoginInfoAsync();

它返回null,因此返回BadRequest()

我到目前为止得到的内容:

Startup.Auth.cs中,我已经掌握了ID和秘密,请注意,我也尝试使用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资料来源:此帖子

额外的FacebookOptions无法解决问题。

我能够从Google和Facebook中检索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"}

我注意到的一个问题是,它将我的名字返回为电子邮件,而不是实际的电子邮件adress。

现在,我想为我的数据库注册外部登录名

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

来源:此帖子

现在,这将在此代码snippit上返回一个badrequest,nesignexternal():

    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中?

aso从这个问题中查看了这个答案,但我不明白如何实施。

此方法并不实际,因为您正在开发API,很可能会用于应用程序,您的最佳方法是通过API消费者使用Facebook处理登录让他们向您发送Facebook Auth Token。

基本上我是在尝试这样做:

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

您想做的是:

  1. API消费者创建了自己的方法,可以使用Facebook登录(通过SDK的应用程序)
  2. API消费者将向API发送Facebook令牌以注册/登录。
  3. API将使用Facebook Graph端点检查令牌。
  4. 成功后,API将返回API的携带者令牌,以提出进一步的认证请求。

因此,对于您作为API开发人员而言,您会像这样验证令牌:

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

,然后获取UserId

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

然后,这一切都取决于您如何创建携带者令牌,如果您遵循下面列出的教程,则可以拥有:

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

来源,在此处提供完整的教程

我还通过SDK收到了电子邮件,并将其与POST请求一起发送,因为我同时管理了API和消费者。但是警告:Facebook用户可能不想给您电子邮件地址。

在Facebook登录后,请在Android和iOS

上获取电子邮件

最新更新