Only load route with existent parametre - laravel

Im doing a crud, i want to show item data using id, i have this in web.php:
Route::get('update/{id}', 'CrudController#update');
How can I deny that the user changes the id in the path to one that does not exist? That shows only those that exist and those that do not, that do not load?

In your update method, you can do the following:
public function update($id)
{
MyModel::findOrFail($id);
//...perform other actions
}
It will throw a 404 response if the requested $id is a non-existent one.
Then you can catch it if you want in the render() method of app\Exceptions\Handler.php:
use Illuminate\Database\Eloquent\ModelNotFoundException;
.
.
.
public function render($request, Exception $exception)
{
if ($exception instanceof ModelNotFoundException) {
if ($request->wantsJson()) {
return response()->json([
'data' => 'Resource not found'
], 404);
} else {
abort(404);
}
}
return parent::render($request, $exception);
}
Or, If you do not want to go through all the trouble of configuring it in the handler, you could also do:
public function update($id)
{
if (! $model = MyModel::find($id)) {
abort(404);
}
//...perform other actions with $model
}
The abort(404) method takes the user to the default Page not found page of laravel, which is an appropriate thing to do.

Related

laravel MethodNotAllowedHttpException redirect to 404

I use laravel 8 tried to edit my exceptions\handler.php
public function render($request, Throwable $exception)
{
if ($exception instanceof MethodNotAllowedHttpException) {
abort(404);
}
return parent::render($request, $exception);
}
but his gives not 404 but 500 when checking routes where MethodNotAllowedHttpException
One possible solution is to supply your routes/web.php file with a Route fallback. Try adding the following to the bottom of your web routes:
Route::fallback( function () {
abort( 404 );
} );
on Laravel 8 override default handler render function on App\Exceptions\Handler.php
public function render($request, Throwable $exception)
{
if ($exception instanceof MethodNotAllowedHttpException) {
if ($request->ajax() || $request->wantsJson() || $request->expectsJson()) {
//405 for Method Not Allowed
return response()->json(['error' => 'Bad Request'], 405);
}
else {
return parent::render($request, $exception);
}
}
}
don't forget to add use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;to test in Postman set key=>Accept ,value => application/json to test handler
reff: Return a 404 when wrong ttp request type used(e.g. get instead of post) in laravel

Globally catch ModelNotFoundException on Laravel 5

I am trying to catch the ModelNotFoundException globally from the app\Exceptions\Handler class, so to not have to check for it on every single controller.
But it does not work, although it works fine from inside a controller:
try {
$asset = Asset::findOrFail($asset_id);
} catch (Exception $e) {
if ($e instanceof ModelNotFoundException)
{
$model = explode('\\', $e->getModel());
return $this->respondWithRecordNotFound(end($model) . ' record not found');
}
return $this->respondWithGeneralError($e->getMessage());
}
app\Exceptions\Handler:
public function render($request, Exception $exception)
{
if ($exception instanceof ModelNotFoundException)
{
$model = explode('\\', $exception->getModel());
return $this->respondWithRecordNotFound(end($model) . ' record not found');
}
return parent::render($request, $exception);
}
I am not sure what your respondWithRecordNotFound is doing. I guess the issue might lie there.
In any case, I just tried it out and this works for me. In App\Exceptions\Handler.php#render
if ($e instanceof \Illuminate\Database\Eloquent\ModelNotFoundException) {
return response()->view(
'errors.404',
["message" => $e->getModel() . ' record not found'],
404
);
}
Just make sure you have added the use in the Handler.php
use \Illuminate\Database\Eloquent\ModelNotFoundException;

Handle jwt auth errors in laravel

I'm working on a rest api project.
I was struggling with an issue. As I get the token expiration error, the generated code will be something like this :
public function authenticate(Request $request){
$this->checkForToken($request);
try {
if (! $this->auth->parseToken()->authenticate()) {
throw new UnauthorizedHttpException('jwt-auth', 'User not found');
}
} catch (JWTException $e) {
throw new UnauthorizedHttpException('jwt-auth', $e->getMessage(), $e, $e->getCode());
}
}
This code is written in this file :
vendor/tymon/jwt-auth/src/Http/Middleware/BaseMiddleware.php
How can I return this as a JSON type?
Catch that exception in your App\Exceptions\Handler class' render method and return a response formatted as json:
// Handler.php
// import the class of the exception you want to render a json response for at the top
use Symfony\Component\HttpKernel\Exception\UnauthorizedHttpException;
...
public function render($request, Exception $exception)
{
// if your api client has the correct content-type this expectsJson()
// should work. if not you may use $request->is('/api/*') to match the url.
if($request->expectsJson())
{
if($exception instanceof UnauthorizedHttpException) {
return response()->json('Unauthorized', 403);
}
}
return parent::render($request, $e);
}

Having a controller on 404 urls using Laravel 5

I need to have a custom controller triggered when user hits a not-existing url or when I programmatically force an App::abort(404).
How can I do it?
My 404 views need some data, and a simple blade View (or a ViewComposer) is not enough.
Thanks
PS catch-all urls is not functional, because they don't catch programmatically launched 404.
Edit the render function of App\Exceptions\Handler class and add something about 404 here:
if ($this->isHttpException($exception) && $this->getStatusCode() == 404) {
// Do what you want...
// You can even use the $request variable
}
Full example:
public function render($request, Exception $exception)
{
if ($this->isHttpException($exception) && $this->getStatusCode() == 404) {
echo 'hello from 404 renderer';
dd($request); // Or you can a view.
}
return parent::render($request, $exception);
}
Try to return a redirect() to your custom Controller instead of a response() from the Handler's render() method if the exception is 404. You can retrieve the the page requested from the $request then right ?
Here is the sample:
public function render($request, Exception $exception)
{
if ($this->isHttpException($exception) && $this->getStatusCode() == 404) {
return redirect(route('route.to.custom.controller'))->with('request', $request);
}
return parent::render($request, $exception);
}
Hope that will help, cheers !

How to use custom middleware with Laravel 404 exception

In my Laravel 5.2 app I have custom middleware called 'cart' that I use to keep track of the users cart contents across different routes.
It looks like this:
class CartMiddleware
{
public function handle($request, Closure $next)
{
$cart = new Cart();
$cart_total = $cart->total();
view()->composer(['layouts.main'], function ($view) use ($cart_total) {
$view->with('cart_total', $cart_total);
});
return $next($request);
}
}
Route::group(['middleware' => ['cart']], function () {
Route::get('cart', 'CartController#show');
});
When ever my app raises a 404 exception the 404.blade.php view cannot render because it is missing the $cart_total that is supplied by the 'cart' middleware.
Is there a way to assign this 'cart' middleware to my exception?
if ($e instanceof HttpException) {
if ($request->ajax()) {
return response()->json(['error' => 'Not Found'], 404);
}
return response()->view('errors.404', [], 404);
}
return parent::render($request, $e);
At Laravel 5.4 and probably some older ones you can modify the file app/exceptions/Handler.php and the function render like this:
if( is_a( $exception, \Symfony\Component\HttpKernel\Exception\NotFoundHttpException::class ) ) {
return redirect()->route( 'error_404' );
}
// ... old code in the function ...
in this way every 404 errors are redirected to certain real route that acts like other routes of site.
You may also submit any data from current request to show a reasonable error at the target.

Resources