Настройка: Новый проект MVC5 с использованием только веб-API. Добавлен Facebook AppId и Secret.
Я могу получить токен для моего веб-API с конечной точки Token
, передав в UserName и Password. Затем используйте этот токен для дальнейших вызовов.
НО
Я хочу регистрировать новых пользователей с помощью Facebook SDK в приложении iOS. Я использую Facebook SDK, чтобы получить токен доступа. (Предположим, в этот момент у меня есть токен доступа).
Следующее, что я знаю, - это вызвать конечную точку api/Account/RegisterExternal
, передав этот токен в заголовке Authorization
с Bearer [Access Token]
, но это приведет к ошибке 500 серверов.
Я думаю, я знаю причину, Cookie отсутствует. Я сделал тот же звонок с файлом cookie от Fidler, и он сработал. (Cookie получен путем перехода к URL-адресу, предоставленному конечной точкой ExternalLogins
).
Поскольку cookie отсутствует await Authentication.GetExternalLoginInfoAsync();
внутри действия RegisterExternal возвращает null.
// POST api/Account/RegisterExternal
[OverrideAuthentication]
[HostAuthentication(DefaultAuthenticationTypes.ExternalBearer)]
[Route("RegisterExternal")]
public async Task<IHttpActionResult> RegisterExternal(RegisterExternalBindingModel model)
{
if (!ModelState.IsValid)
{
return BadRequest(ModelState);
}
var info = await Authentication.GetExternalLoginInfoAsync();
if (info == null)
{
return InternalServerError();
}
var user = new ApplicationUser() { UserName = model.Email, Email = model.Email };
IdentityResult result = await UserManager.CreateAsync(user);
if (!result.Succeeded)
{
return GetErrorResult(result);
}
result = await UserManager.AddLoginAsync(user.Id, info.Login);
if (!result.Succeeded)
{
return GetErrorResult(result);
}
return Ok();
}
Я не хочу делать 3 вызова в моем веб-API, чтобы запросить внешние логины, а затем перейти к этому URL-адресу и пройти аутентификацию в токене доступа к веб-обозревателю для доступа к Facebook, а затем вызвать конечную точку RegisterExternal с этим токеном доступа и Cookie, чтобы я необходимо собирать между этими вызовами.
Как я уже сказал, я ничего не менял в шаблоне, кроме идентификаторов Facebook. Тем не менее код выглядит следующим образом.
public partial class Startup
{
public static OAuthAuthorizationServerOptions OAuthOptions { get; private set; }
public static string PublicClientId { get; private set; }
// For more information on configuring authentication, please visit http://go.microsoft.com/fwlink/?LinkId=301864
public void ConfigureAuth(IAppBuilder app)
{
// Configure the db context and user manager to use a single instance per request
app.CreatePerOwinContext(ApplicationDbContext.Create);
app.CreatePerOwinContext<ApplicationUserManager>(ApplicationUserManager.Create);
// Enable the application to use a cookie to store information for the signed in user
// and to use a cookie to temporarily store information about a user logging in with a third party login provider
app.UseExternalSignInCookie(DefaultAuthenticationTypes.ExternalCookie);
// Configure the application for OAuth based flow
PublicClientId = "self";
OAuthOptions = new OAuthAuthorizationServerOptions
{
TokenEndpointPath = new PathString("/Token"),
Provider = new ApplicationOAuthProvider(PublicClientId),
AuthorizeEndpointPath = new PathString("/api/Account/ExternalLogin"),
AccessTokenExpireTimeSpan = TimeSpan.FromDays(14),
AllowInsecureHttp = true
};
// Enable the application to use bearer tokens to authenticate users
app.UseOAuthBearerTokens(OAuthOptions);
app.UseFacebookAuthentication(
appId: "xxxxxxxxxxxxxxx",
appSecret: "xxxxxxxxxxxxxxxxxxxxxxxx");
}
}
Насколько я знаю, веб-API не нужен Cookie, и это выглядит правдивым, если у меня есть локальный токен из конечной точки Token
, но зачем это нужно для Cookie, в первую очередь при выполнении ExternalRegister
Класс WebApiConfig выглядит так и не должен config.SuppressDefaultHostAuthentication();
избегать любых потребностей в Cookie.
public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{
// Web API configuration and services
// Configure Web API to use only bearer token authentication.
config.SuppressDefaultHostAuthentication();
config.Filters.Add(new HostAuthenticationFilter(OAuthDefaults.AuthenticationType));
// Web API routes
config.MapHttpAttributeRoutes();
config.Routes.MapHttpRoute(
name: "DefaultApi",
routeTemplate: "api/{controller}/{id}",
defaults: new { id = RouteParameter.Optional }
);
}
}
Я не знаю, не упущен ли я здесь. Мои намерения не должны использовать веб-браузер в родном приложении iOS для токена. Это Facebook SDK, чтобы получить токен доступа и использовать этот вызов RegisterExternal
, чтобы получить локальный токен и создать идентификатор пользователей.
Я сделал домашнее задание, и я застрял в этой мысли. Мысли оценили!