Регистрация веб-интерфейса внешнего входа
Я не понимаю, почему они не являются ясным руководством или руководством по этому вопросу, поэтому я надеюсь, что на мой вопрос можно ответить здесь.
Итак, пытаясь зарегистрировать пользователей из 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