Регистрация веб-интерфейса внешнего входа

Я не понимаю, почему они не являются ясным руководством или руководством по этому вопросу, поэтому я надеюсь, что на мой вопрос можно ответить здесь.

Итак, пытаясь зарегистрировать пользователей из facebook или google, через Web Api.

Проблема заключается в методе 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 source: этот пост

Эта дополнительная функция facebookOpions не решила проблему.

Я могу получить access_token как из 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"}

Одна из проблем, которые я замечаю, заключается в том, что он возвращает мое имя как адрес электронной почты, а не фактический адрес электронной почты.

Теперь я хочу зарегистрировать внешний логин с новым пользователем для моей базы данных, который я делаю для вызова POST следующим образом:

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

источник: этот пост

Теперь это возвращает BadRequest в этом фрагменте кода, внутри 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 он идет настолько гладко, почему бы и нет в веб-API?

Aso посмотрел этот ответ из на этот вопрос, но я не понимал, как реализовать это.

Ответ 1

Этот метод не очень практичен, так как вы разрабатываете API, который, скорее всего, будет использоваться для приложений, вам лучше всего обработать логин с помощью facebook от потребителя API и позволить им отправить вам токен аутентификации facebook.

В основном я пытался это сделать:

  • Создайте внешнюю ссылку для входа в facebook.
  • Отправьте пользователя на эту ссылку, которая приведет их на страницу входа в facebook.
  • После входа в систему facebook перенаправит api.
  • Пользователь будет зарегистрирован, но как узнает приложение/веб-сайт, потребляющий API?

Что вы хотите сделать:

  • Пользователь API создает свой собственный метод для входа в facebook (для приложений через SDK)
  • Пользователь API будет отправлять токен facebook в API для регистрации/входа в систему.
  • API проверит токен с конечной точкой графика facebook.
  • Когда это удается, 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