Проблема при попытке отправить форму от имени неавторизованного пользователя

#c# #asp.net-mvc #asp.net-identity

#c# #asp.net-mvc #asp.net-identity

Вопрос:

Извините за название, но я не знал, как объяснить это всего в одном предложении. У меня есть представление с формой:

 @using (Html.BeginForm("AddComment", "Restaurants"))
{
    @Html.TextBoxFor(c => c.NewComment.Body)
    @Html.HiddenFor(m => m.Restaurant.Id)
    <button type="submit">Add comment</button>
}
  

И действие AddComment в контроллере ресторанов:

 public ActionResult AddComment(RestaurantViewModel model, Comment newComment)
{
    var userId = User.Identity.GetUserId();
    var user = _context.Users.FirstOrDefault(u => u.Id == userId);

    newComment.RestaurantId = model.Restaurant.Id;
    newComment.AuthorId = Guid.Parse(userId);
    newComment.AuthorName = user.UserName;
    newComment.DateTime = DateTime.Now;

    _context.Comments.Add(newComment);
    _context.SaveChanges();

    return RedirectToAction("Details", "Restaurants", new { id = model.Restaurant.Id});
}
  

И я добавил фильтр авторизации:

 filters.Add(new AuthorizeAttribute());
  

Когда я пытаюсь отправить форму от имени не зарегистрированного пользователя, она перенаправляет меня на страницу входа. Если я вхожу на эту страницу, она вызывает AddComment действие, но передает аргументы Model.Restaurant и NewComment.Body в виде нулей. Как это исправить, чтобы при входе в систему меня перенаправляли на предыдущую страницу с заполненным текстовым полем или просто вызывали AddComment , но передавали правильные значения аргументов.

Комментарии:

1. Если вы добавите фильтр, требующий авторизации пользователя при каждом действии, а пользователь не авторизован, что, по вашему мнению, должно было произойти? Рассматривали ли вы вместо этого требование авторизации только для методов действий, которым требуется авторизация?

2. Я ожидал чего-то подобного: я не вошел в систему => Я нажимаю кнопку Добавить комментарий => перенаправлен на страницу входа => Я вхожу в систему => перенаправлен на страницу с формой добавления комментария. В данный момент я получаю следующее: я не вошел в систему => Я нажимаю кнопку Добавить комментарий => перенаправлен на страницу входа => Я вхожу в систему => Вызывается действие AddComment, а переданные аргументы равны нулю. Если я нажму добавить комментарий, когда я уже вошел в систему, все работает, переданные аргументы в порядке.

Ответ №1:

Для этого нет встроенного способа. Причина в том, что это не «способ ведения дел». Если у вас есть форма с защищенным действием POST, также сделайте соответствующую страницу GET аутентифицированной-только для аутентификации.

Комментарии:

1. Использование filters.Add(new AuthorizeAttribute()); означает, что каждое отдельное действие, независимо от его типа, защищено с помощью [Authorize] . Это, безусловно, может произойти, если срок действия сеанса истек после перехода на эту страницу

Ответ №2:

Попробуйте удалить эту строку:

 filters.Add(new AuthorizeAttribute());
  

И добавление обозначения [Authorize] к вашему методу, например:

 [Authorize]
public ActionResult AddComment(RestaurantViewModel model, Comment newComment)
{
    var userId = User.Identity.GetUserId();
    var user = _context.Users.FirstOrDefault(u => u.Id == userId);

    newComment.RestaurantId = model.Restaurant.Id;
    newComment.AuthorId = Guid.Parse(userId);
    newComment.AuthorName = user.UserName;
    newComment.DateTime = DateTime.Now;

    _context.Comments.Add(newComment);
    _context.SaveChanges();

    return RedirectToAction("Details", "Restaurants", new { id = model.Restaurant.Id});
}
  

Ответ №3:

Я не предлагаю делать это за пределами простейших случаев. Вы можете изменить свою форму, чтобы использовать get вместо post :

 @using (Html.BeginForm("AddComment", "Restaurants", FormMethod.Get))
{
    @Html.TextBoxFor(c => c.NewComment.Body)
    @Html.HiddenFor(m => m.Restaurant.Id)
    <button type="submit">Add comment</button>
}
  

Предостережения:

  • Это сработает, только если вы используете встроенную аутентификацию или ваша реализация пересылает значения querystring.
  • Во-вторых, значения будут в URL, поэтому их можно легко подделать.
  • И последнее, но не менее важное: если у AddComment есть HttpPost атрибут, вам придется удалить его.