Как я должен использовать ReturnUrl = ViewBag.ReturnUrl в MVC 4
Я работаю над приложением ASP.NET MVC 4. Я использую/изучаю SimpleMembershipProvider и пытаюсь придерживаться логики по умолчанию, созданной VS2012
с помощью Internet template
(если я не ошибаюсь, тот, у кого есть SimpleMembershipProvider).
Я застрял в AccountController
, где я просто не могу понять, как именно я могу использовать этот метод:
private ActionResult RedirectToLocal(string returnUrl)
{
if (Url.IsLocalUrl(returnUrl))
{
return Redirect(returnUrl);
}
else
{
return RedirectToAction("Index", "Home");
}
}
Из того, что я понимаю, вся идея состоит в том, чтобы перенаправить на место, из которого вы решили войти (именно то, что я хочу выполнить). Я посмотрел, как он используется в представлении:
@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl }))
Найдите место, где на самом деле ViewBag.ReturnUrl
задано какое-то значение, и я получил этот метод только здесь:
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
и я очень запутался в том, как именно я должен получить местоположение /url. Я установил некоторые точки останова, и я никогда не видел, чтобы returnUrl
был чем-то отличным от null
, который в этом сценарии кажется мне довольно логичным, так как он нигде не получает значения (если не пропустить что-то, конечно).
Так что я действительно не могу понять, как эта работа. Я публикую выше, чтобы показать, что я пытался сделать домашнее задание, я расследую столько, сколько мог, но я не нашел ответа, поэтому я прошу здесь. Не могли бы вы дать объяснение/пример того, как это работает?
Ответы
Ответ 1
При использовании проверки подлинности форм и не авторизовано или не авторизовано, что конвейер безопасности ASP.NET будет перенаправлен на страницу входа в систему и передать в качестве параметра строку запроса returnUrl, равную странице, перенаправленной на страницу входа. Действие login захватывает значение этого параметра и помещает его в ViewBag, поэтому его можно передать в представление.
[AllowAnonymous]
public ActionResult Login(string returnUrl)
{
ViewBag.ReturnUrl = returnUrl;
return View();
}
Затем View сохраняет это значение в форме, как показано этой строкой кода в представлении.
@using (Html.BeginForm(new { ReturnUrl = ViewBag.ReturnUrl }))
Причина, по которой он хранится в представлении, заключается в том, что когда пользователь делает Submit после ввода своего имени пользователя и пароля, действие контроллера, которое обрабатывает сообщение, будет иметь доступ к этому значению.
[HttpPost]
[AllowAnonymous]
[ValidateAntiForgeryToken]
public ActionResult Login(LoginModel model, string returnUrl)
{
if (ModelState.IsValid && WebSecurity.Login(model.UserName, model.Password, persistCookie: model.RememberMe))
{
return RedirectToLocal(returnUrl);
}
// If we got this far, something failed, redisplay form
ModelState.AddModelError("", "The user name or password provided is incorrect.");
return View(model);
}
Если состояние модели является допустимым, и они аутентифицируются путем вызова метода WebSecurity.Login, то он вызывает метод RedirectToLocal со значением returnUrl, который пришел из представления, который изначально появился в результате действия входа, которое создало представление.
Значение returnUrl будет равно null, если пользователь не будет перенаправлен на страницу входа в систему, как в случае, когда они просто нажимают ссылку входа в верхней части страницы в макете по умолчанию. В этом случае пользователь будет перенаправлен на домашнюю страницу после успешного входа в систему. Вся цель returnUrl заключается в том, чтобы автоматически отправить пользователя обратно на страницу, к которой они пытались получить доступ, до того, как они были аутентифицированы/авторизованы.
Ответ 2
Это потому, что шаблон ASP.NET MVC по умолчанию использует Аутентификацию форм, а контроллеры украшены атрибутом [Authorize]
:
<authentication mode="Forms">
<forms loginUrl="~/Account/Login" timeout="2880" />
</authentication>
[Authorize]
public class AccountController : Controller
{
//...
}
Это означает, что если пользователь не аутентифицирован, он будет перенаправлен на страницу входа в систему, определенную в атрибуте LoginUrl элемента формы.
Во время перенаправления FormsAuthentication
, который является HttpModule
, автоматически добавит URL-адрес, который был запрошен в строке запроса.
Итак, если вы перейдете к /Account/Login
, вы не получите ничего в строке запроса, так как оно украшено атрибутом [AllowAnonymous]
.
Но если вы перейдете к /Account/Manage
, вы заметите, что returnUrl в строке запроса станет /Account/Manage
(/Account/Login?ReturnUrl=%2fAccount%2fManage)
Итак, вы не устанавливаете returnUrl, фреймворк делает это за вас, вы просто используете его в AccountController
, чтобы узнать, куда перенаправить пользователя после его аутентификации.
Ответ 3
Когда пользователь, не прошедший проверку подлинности, пытается попасть в раздел вашего приложения, для которого требуется аутентификация, на картинке появляется returnUrl
. Url, запрошенный неаутентифицированным пользователем, в основном хранится в returnUrl
.
Вы можете пройти через Учебник PluralSight: Создание приложений с помощью ASP.NET MVC 4