We face an interesting balance as developers. We want to keep our code maintainable, yet we also want to keep things concise, and we never want to repeat ourselves. I think that this battle is very present in the war of whether to use back redirects in our server-side code. The alternative is to describe which route to redirect to.
Maintainability
One of the major concerns with using a backward redirect is the thought that you want to make sure that you are redirecting the user back to a predictable route. You wouldn't want to think you are flashing the session with a bunch of helpful messages and then have an unpredicted route completely ignore these messages (and then having them sit in the session until they are read or overwritten in some cases). While I understand the merits of this idea and the readability of knowing "Ok, this is the route that needs to accept this data", I think that there are three big concerns that this ignores.
Change
This argument is the most simple, if the original route changes, you will have to go back and update your update method. Things like route or action naming can only go so far to alleviating this issue. A redirect back will not break no matter how your code changes.
Reusability
Part of making maintainable code is not repeating yourself where it is unnecessary.
Think of a sign up form with coupon codes based on the referrer found in the url (let's say you're building an affiliate site).
When you build your site, you may have a signup form at yoursite.com/signup
.
But, your referrals come from yoursite.com/refer/{referrerId}
.
Even with the best abstraction, you can post both forms to the same controller action. The normal site just won't have a value for the referrer and your business logic should be able to handle this. But, if you were to explicitly redirect to a route, you would have to either use two different controller actions or muddle up your controller with conditionals to figure out where to redirect to.
Security
The key use for back redirects is when submitting forms and needing a change. You are redirecting because some of the input was bad. Now this is great for users on a browser. For all back redirects you will be accepting required data (more on this later).
The standard web browser user (where we care about UX), cannot POST to your route except through a form (or javascript driven form submission). Therefore, it makes sense that we should be able to use redirect back and assume that they will be redirected back to a page that knows how to handle session or HTTP header info for the request. There are two scenarios where this is not true.
First is the user that POSTs form data to your route from a requester that does not know how to handle the data sent back with the redirect. Second is the manually entered data which will not have a header entry for the requesting page (leading redirect back to throw an error). Both of these should be treated as malicious attacks on your site and both of these situations are acceptable.
In neither case would you want to redirect them to the expected route. If a user does happen to be submitting a form from a external site that is legitimate, you wouldn't want to change their user experience and bring them into your site. Otherwise, if the request is malicious, you wouldn't then want to send them to the proper form. If you do, you are basically saying "I know that you put in bad data before, but here's a form that you can use to maliciously attack this service."
** Note **
Proper error or redirects are not a sole line of defense in your security. Security precautions such as CSRF filtering, mass assignment prevention, and other tactics should also be included in your security plan.
When To Use Back Redirects
So, the question becomes when to redirect back? Redirect back should only be used for UX when you have browser form that is POSTing (this includes fake HTTP methods in frameworks as well). This prevents accidental address entering to throw an error where there is no header data to redirect back in the case of GET requests.
I have to rephrase that. NEVER. EVER. EVER! Redirect back on a GET request. GET requests include a lot of manual entry into the requesting url. Whether through links or hand typing, these can go wrong, and you should expect them to go wrong. So, an error response is the way to go (not a redirect)!
So, do you agree? Are back redirects good or bad? Am I just being lazy and should I go back to being more explicit in my programming?