简体   繁体   中英

Problem when trying to submit form as a not authorized user

Sorry for the title but I didn't know how to explain it in just one sentence. I have a view with form:

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

And AddComment Action in Restaurants controller:

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});
}

And I added authorize filter:

filters.Add(new AuthorizeAttribute());

When I try to submit a form as a not logged user, it redirects me to the log in page. If I log in on that page, it calls AddComment Action but it pass arguments Model.Restaurant and NewComment.Body as nulls. How to fix it, so when I log in, it redirects me to the previous page with filled TextBox or just call AddComment but pass proper values of arguments.

There is no built-in way to do this. The reason is, that this is not "the way of doing things". If you have a form with a secured POST action, make the corresponding GET page authenticated-only as well.

Try removing this line:

filters.Add(new AuthorizeAttribute());

And adding the notation [Authorize] to your method, like:

[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});
}

I don't suggest doing this outside of the simplest of cases. You can change your form to use get instead of 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>
}

Caveats:

  • This only will work if you use the built in auth, or your implementation forwards querystring values.
  • Second, the values will be in the URL, so they can be tampered with easily.
  • Last, but not least, if AddComment has the HttpPost attribute, you will have to remove that.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM