-
Notifications
You must be signed in to change notification settings - Fork 10.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[5.9] Consider request validation before authorization #27808
Comments
Proposals should be sent to https://github.com/laravel/ideas/issues since the framework Issues are meant for bug reports: https://laravel.com/docs/5.8/contributions#bug-reports <?php
namespace App\Http\Requests;
trait AuthorizesAfterValidation
{
public function authorize()
{
return true;
}
public function withValidator($validator)
{
$validator->after(function ($validator) {
if (! $validator->failed() && ! $this->authorizeValidated()) {
$this->failedAuthorization();
}
});
}
abstract public function authorizeValidated();
} class UpdateCommentRequest extends FormRequest
{
use AuthorizesAfterValidation;
public function authorizeValidated()
{
return $this->user()->can('update', Comment::find($this->input('comment_id')));
}
public function rules()
{
return [
'comment_id' => 'required|int|exists:comments,id', // runs a duplicate database query
];
}
} For your example, the most appropriate response is a HTTP 404 status code if the comment isn't found. The resource to authorize doesn't exist. Laravel handles this case by using route model binding, no FormRequest necessary: class CommentsController
{
/**
* PUT /comments/{comment}
*/
public function update(Comment $comment)
{
$this->authorize('update', $comment);
}
} Also have a look at the class UpdateCommentRequest extends FormRequest
{
public function authorize()
{
return $this->user()->can('update', $this->comment());
}
public function rules()
{
return [
// no exists rule needed
];
}
// $request->comment() in the controller won't hit the database again
public function comment()
{
return once(function () {
// ModelNotFoundException thrown
return Comment::findOrFail($this->input('comment_id'));
});
}
} Either way, further discussion should be sent to the "laravel/ideas" Issues. |
Heya, thanks for submitting this. This seems like a feature request or an improvement. It's best to post these at the laravel/ideas repository to get support for your idea. After that you may send a PR to the framework. Please only use this issue tracker to report bugs and issues with the framework. |
Thanks @derekmd - My example was a bit too simplistic. I have a hard time imagining there'd be much support to change this anyways, so I'll stick to a trait-based approach as you recommended. Thanks. |
Description:
A long, long time ago, a PR was merged that changed the order of operations for the
ValidatesWhenResolvedTrait
: #6407I'm creating this issue to see if there would be an opportunity to either:
The reason I believe the order should be:
validate input
->authorize
is because there are often times where the authorization logic needs to reference the request input. If the input has not yet been validated (as is current functionality), there are two problems:authorize
methodTaking a slightly modified example from the Laravel documentation:
If the user making this request specifies a nonexistent
comment_id
, I think it can be argued that the correct response is 422.In addition, if the request input validation happened prior to the authorization, the authorize method could be cleaned up, since we're 100% sure the comment exists:
I'm more than willing to submit the PR for this, but I'd like to know if there's a chance it will be accepted (and which direction would be preferred).
The text was updated successfully, but these errors were encountered: