Изменить маршрутизацию в ASP.NET Core Identity UI?
Я использую новый пакет пользовательского интерфейса Identity, доступный с момента выпуска ASP.NET Core 2.1. Используя недавно созданный проект MVC, вот некоторые URL-адреса страниц, которые доступны:
/Home/About
/Home/Contact
/Identity/Account/Login
/Identity/Account/Register
Как настроить маршрутизацию для удаления /Identity/
часть из URL-адресов?
Ответы
Ответ 1
Похоже, это еще не возможно. Если посмотреть на исходный код, то ясно, что имя области жестко закодировано в IdentityDefaultUIConfigureOptions<TUser>
:
private const string IdentityUIDefaultAreaName = "Identity";
Это используется в нескольких местах, в том числе при настройке страниц Razor. например:
options.Conventions.AuthorizeAreaFolder(IdentityUIDefaultAreaName, "/Account/Manage");
А также при настройке аутентификации Cookies. например:
options.LoginPath = $"/{IdentityUIDefaultAreaName}/Account/Login";
Стоит отметить, что IdentityDefaultUIConfigureOptions<TUser>
сам защищен, поэтому возможность переопределять параметры не существует.
Я открыл вопрос Github, чтобы узнать, можем ли мы получить отзывы от тех, кто участвует в самом проекте.
Обновление 2018-06-12
Хавьер Кальварро Нельсон из команды Core Identity ASP.NET предоставил некоторые ценные отзывы в выпуске Github, который я поднял, который можно резюмировать следующим образом:
Основная причина, по которой пользовательский интерфейс Identity должен находиться в зоне, - это минимизировать влияние на ваше приложение и обеспечить четкое разделение между вашим кодом приложения и кодом Identity.
Хавьер рекомендует один из следующих вариантов, когда вы хотите настроить URL-адреса:
- Используйте элемент леса для пользовательского интерфейса по умолчанию и сделайте все необходимые настройки самостоятельно.
- Используйте правило перенаправления, которое указывает старые маршруты на новые маршруты.
- Не используйте пользовательский интерфейс по умолчанию.
Несмотря на то, что Хавьер не поддерживается и не рекомендуется, Хавьер также указывает, что для переопределения URL-адресов можно использовать пользовательскую IPageApplicationModelConvention
. Однако, если вы его пропустили, это не поддерживается и не рекомендуется.
2018-06-27 Обновление
Официальная документация теперь обновлена, чтобы лучше объяснить упомянутые изменения URL.
Ответ 2
В вашем startup.cs вы можете изменить:
services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
с:
services.AddMvc().AddRazorPagesOptions(o => o.Conventions.AddAreaFolderRouteModelConvention("Identity", "/Account/", model =>
{
foreach (var selector in model.Selectors)
{
var attributeRouteModel = selector.AttributeRouteModel;
attributeRouteModel.Order = -1;
attributeRouteModel.Template = attributeRouteModel.Template.Remove(0, "Identity".Length);
}
})
).SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
Он будет маршрутизировать:
/Идентификация/Учетная запись/Вход в систему /Счет/Вход
/Идентификация/Учетная запись/Регистрация в /Учетная запись/Регистрация
так далее...
Чтобы обработать ReturnUrl, вы можете создать новое действие:
[Route("Identity/Account/Login")]
public IActionResult LoginRedirect(string ReturnUrl)
{
return Redirect("/Account/Login?ReturnUrl=" + ReturnUrl);
}
Ответ 3
Что касается маршрутизации, то его стандарт в веб-фреймах, чтобы URL-адреса аутентификации были исправлены, Django делает то же самое. Здесь, как настроить представление по своему вкусу, поэтому вместо удаления /Identity/из маршрутов мы сообщим Identity не включать их представления и предоставить маршрут нашим.
Перейдите в Startup.cs
:
// USE METHOD WITH LESS DEFAULTS
//
// services.AddDefaultIdentity<IdentityUser>()
// .AddEntityFrameworkStores<ApplicationDbContext>();
services.AddIdentity<IdentityUser, IdentityRole>(options => options.Stores.MaxLengthForKeys = 128)
.AddEntityFrameworkStores<ApplicationDbContext>()
.AddDefaultTokenProviders();
//
// ADD A ROUTE BELOW THE DEFAULT ROUTE
//
routes.MapRoute(
name: "identity",
template: "Identity/{controller=Account}/{action=Register}/{id?}");
Теперь у нас есть все настройки, но вид, поэтому нам нужно сделать маршрут к нему так, как мы обычно делаем в mvc. Создайте контролер учетной записи. Изменить индекс() на регистр(). Создайте папку в представлениях с именем Account. Добавьте файл Register.cshtml
, здесь оригинальный html, настройте в соответствии с вашими потребностями:
<div class="container body-content">
<h2>Register</h2>
<div class="row">
<div class="col-md-4">
<form method="post" action="/Identity/Account/Register" novalidate="novalidate">
<h4>Create a new account.</h4>
<hr>
<div class="text-danger validation-summary-valid" data-valmsg-summary="true"><ul><li style="display:none"></li>
</ul></div>
<div class="form-group">
<label for="Input_Email">Email</label>
<input class="form-control" type="email" data-val="true" data-val-email="The Email field is not a valid e-mail address." data-val-required="The Email field is required." id="Input_Email" name="Input.Email" value="">
<span class="text-danger field-validation-valid" data-valmsg-for="Input.Email" data-valmsg-replace="true"></span>
</div>
<div class="form-group">
<label for="Input_Password">Password</label>
<input class="form-control" type="password" data-val="true" data-val-length="The Password must be at least 6 and at max 100 characters long." data-val-length-max="100" data-val-length-min="6" data-val-required="The Password field is required." id="Input_Password" name="Input.Password">
<span class="text-danger field-validation-valid" data-valmsg-for="Input.Password" data-valmsg-replace="true"></span>
</div>
<div class="form-group">
<label for="Input_ConfirmPassword">Confirm password</label>
<input class="form-control" type="password" data-val="true" data-val-equalto="The password and confirmation password do not match." data-val-equalto-other="*.Password" id="Input_ConfirmPassword" name="Input.ConfirmPassword">
<span class="text-danger field-validation-valid" data-valmsg-for="Input.ConfirmPassword" data-valmsg-replace="true"></span>
</div>
<button type="submit" class="btn btn-default">Register</button>
<input name="__RequestVerificationToken" type="hidden" value="CfDJ8IWbPHM_NTJDv_7HGewWzbbRveP09yQOznYdTWL2aN5X_4_eVbNE1w8D_qz7zegloVtdAhuVOJbJLQo0ja73FB3PgYycyGpn-DfX3fJqv4Cx8ns6Ygh6M7nMxV0eozO7hoDxUfPwrIJb2RcFtyzhPpMevZ4P0M8aVyBP55SP-5C4l23dCtDXXUOAY_YLwt67dw"></form>
</div>
</div>
<hr>
<footer>
<p>© 2018 - SqlServerApp</p>
</footer>
</div>
Ответ 4
Самое простое - перетащить папку "Страницы" из области/идентификатора в главный проект. Помните, что директива @page (в.cshtml) заставляет взгляды быть доступными напрямую для чего-либо в разделе "Страницы" (страница превращается в действие). Вы также можете переименовать папку "Учетная запись" на другое имя, если хотите изменить страницы по умолчанию/Учетная запись/Логин и т.д.
директива @page также может использоваться для указания настраиваемого пути, например: @page "/Login"
получить доступ к странице входа напрямую, перейдя в/Логин
Ответ 5
Промежуточное программное обеспечение перезаписи URL может быть решением:
var options = new RewriteOptions()
.AddRewrite(@"^Account/(.*)", "Identity/Account/$1", skipRemainingRules: true);
app.UseRewriter(options);