I use laravel5.5 for a web program. But when the program is exception, the middleware don't work.
what should i do for it?
my middleware code is list:
namespace App\Http\Middleware;
use Closure;
class ApiException
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string|null $guard
* #return mixed
*/
public function handle($request, Closure $next)
{
$response = $next($request);
$env = config('app.env');
$statusCode = $response->getSatusCode();
if ($statusCode >= 500 && $env != 'dev') {
$response->setContent(['error' => 'Internal Server Error']);
}
return $next($request);
}
}
thank you help me !
There is no way you can do that in Middlewares. You can control exceptions in your app\Exceptions\Handler.php instead.
In middleware can't but in Exception/Handler can..
anytime the exception occurred.. it not entered the middleware, it entered Exception/Handler.php..
in render method
public function render($request, Exception $exception)
{
if ($exception->getCode() >= 500 ||) {
//return redirect()->route(); do something here
}
return parent::render($request, $exception);
}
Related
I have no idea why I keep getting this lately by just simply navigate between pages.
Call to a member function setCookie() on null
This is what I have in my AdminMiddleware
<?php
namespace App\Http\Middleware;
use App\Article;
use Closure, View, Auth ;
use Illuminate\Contracts\Auth\Guard;
class AdminMiddleware
{
/**
* The Guard implementation.
*
* #var Guard
*/
protected $auth;
/**
* Create a new filter instance.
*
* #param Guard $auth
* #return void
*/
public function __construct(Guard $auth)
{
$this->auth = $auth;
}
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if ( Auth::user()->type !== "Admin") {
return View::make('layouts.share.errors.404');
}
return $next($request);
}
}
I'm on Laravel 5.8.
The error occurs when you are logged in as a non Admin because you are returning a View in your AdminMiddleware instead of a Response.
Replace:
if ( Auth::user()->type !== "Admin") {
return View::make('layouts.share.errors.404');
}
With:
if ( Auth::user()->type !== "Admin") {
return response()->view('layouts.share.errors.404', [], 404);
}
To expand on #Chin Leung's answer and to properly return a 404 not found status code
if ( Auth::user()->type !== "Admin") {
return response()->view('layouts.share.errors.404', [], 404);
}
In my web.php I have a route
Route::get('summary_average_fee', 'Summary#AverageFee')->middleware('CheckParams#dateLimits');
Im trying to refrence the dateLimits function in the CheckParams class
My CheckParams class, saved as CheckParams.php in the Middleware folder
<?php
namespace App\Http\Middleware;
use Closure;
class CheckParams
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function dateLimits($request, Closure $next)
{
isEmpty($request->input('startDate'), 'NO_START_DATE');
isEmpty($request->input('endDate'), 'NO_END_DATE');
return $next($request);
}
private function isEmpty($value, $error, $status)
{
if(empty($value))
{
return response()->json($error, 422);
}
}
}
In the kernal.php file I add this to the routeMiddleware array
'CheckParams' => \App\Http\Middleware\CheckParams::class
When it runs, I get the error that Class CheckParams#dateLimits does not exist
Seems to me that your middleware should be rewritten and update the usage:
use App\Http\Middleware\CheckParams;
Route::get('summary_average_fee', 'Summary#AverageFee')->middleware(CheckParams::class);
Middleware:
namespace App\Http\Middleware;
use Closure;
class CheckParams
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$this->isEmpty($request->input('startDate'), 'NO_START_DATE');
$this->isEmpty($request->input('endDate'), 'NO_END_DATE');
return $next($request);
}
private function isEmpty($value, $error, $status)
{
if(empty($value))
{
return response()->json($error, 422);
}
}
}
I am using Laravel 5.5 and trying to implement multi authentication for users and admin. I am getting this error when i try to call admin login form in browser.
Error :
Declaration of App\Exceptions\Handler::unauthenticated($request, App\Exceptions\AuthenticationException $exception) should be compatible with Illuminate\Foundation\Exceptions\Handler::unauthenticated($request, Illuminate\Auth\AuthenticationException $exception)
Here is my unauthenticated function in app/Exceptions/Handler:
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
$guard = array_get($exception->guards(), 0);
switch ($guard) {
case 'admin':
$login = 'admin.login';
break;
default:
$login = 'login';
break;
}
return redirect()->guest(route($login));
}
Please help me to resolve this issue.
You forgot to add use Illuminate\Auth\AuthenticationException at the top of your file
I am using Laravel 7.X
And I prefer to do that in Authenticate middleware
I did it like bellow and It is working well for me.
namespace App\Http\Middleware;
use Closure;
use Illuminate\Auth\Middleware\Authenticate as Middleware;
use Illuminate\Support\Arr;
class Authenticate extends Middleware
{
protected $guards = [];
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #param string[] ...$guards
* #return mixed
*
* #throws \Illuminate\Auth\AuthenticationException
*/
public function handle($request, Closure $next, ...$guards)
{
$this->guards = $guards;
return parent::handle($request, $next, ...$guards);
}
/**
* Get the path the user should be redirected to when they are not authenticated.
*
* #param \Illuminate\Http\Request $request
* #return string|null
*/
protected function redirectTo($request)
{
if (! $request->expectsJson()) {
if (Arr::first($this->guards) === 'admin') {
return route('admin.login');
}
return route('trainee.login');
}
}
}
Thank you for your recent answer Thanh Nguyen. My custom auth middleware is work with the latest version
if (Arr::first($this->guards) === 'admin') {
return route('admin.login');
}
return route('customer.login');
Previously using unauthenticated function inside Handler.php to replace the parent function.
protected function unauthenticated($request, AuthenticationException $exception)
{
$guard = Arr::get($exception->guards(), 0);
switch ($guard) {
case 'respondent':
$login = 'respondents.login';
break;
case 'admin':
$login = 'admin.login';
break;
default:
$login = 'admin.login';
break;
}
return $request->expectsJson()
? response()->json(['message' => $exception->getMessage()], 401)
: redirect()->guest(route($login));
}
Both is working, but there was likely an issue for latest version on array_get to obtain guards we use:
$guard = array_get($exception->guards(), 0);
For anyone facing this issue, this method has been deprecated for Laravel 7.* and above
Error in Handler Class - Laravel
public function handle($request, Closure $next)
With
public function handle($request, Closure $next, ...$auth)
Hello I have an issue with laravel localization
I've made language switcher and currently selected language doesn't work on 404 pages (it works if I return abort(404) in controller manualy), it always shows content on default locale defined in config/app.php
My middleware code
<?php
namespace App\Http\Middleware;
use Closure;
class SetLanguageCookie
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
if($request->hasCookie('language')) {
$cookie = $request->cookie('language');
app()->setLocale($cookie);
return $next($request);
} else {
$response = $next($request);
$response->withCookie(cookie()->forever('language', 'en'));
return $response;
}
}
}
Any ideas how can I make this working? So all automaticaly shown 404 pages show content in currently selected language?
If you have default error handling, look for this file:
app\Exceptions\Handler.php
Change the render method to something like this:
/**
* Render an exception into an HTTP response.
*
* #param \Illuminate\Http\Request $request
* #param \Exception $e
* #return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
if($e instanceof NotFoundHttpException)
{
if(\Request::hasCookie('language')) {
$cookie = \Request::cookie('language');
app()->setLocale($cookie);
//.... etc
}
}
return parent::render($request, $e);
}
Fixed it with help of #ArthurSamarcos
app/Exceptions/Handler.php
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
/**
* Render an exception into an HTTP response.
*
* #param \Illuminate\Http\Request $request
* #param \Exception $e
* #return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
if($request->hasCookie('language')) {
// Get cookie
$cookie = $request->cookie('language');
// Check if cookie is already decrypted if not decrypt
$cookie = strlen($cookie) > 2 ? decrypt($cookie) : $cookie;
// Set locale
app()->setLocale($cookie);
}
if($e instanceof NotFoundHttpException) {
return response()->view('errors.404', [], 404);
}
return parent::render($request, $e);
}
I'm building RESTful API with Laravel. My API always returns JSON. What I would like to do, is keeping response logic at one place. Here's how I do it right now in API controller, which is pointed to by Route::controller(). Funny and ultra-useful example coming:
public function getDouble($number) {
try {
if (!is_numeric($number)) {
throw new HttpException(400, 'Invalid number.');
}
$response = $number * 2;
$status = 200;
}
catch (HttpException $exception) {
$response = $exception->getMessage();
$status = $exception->getStatusCode();
}
return response()->json($response, $status);
}
In this example, my API route would be for example /double/13 accessed by GET method. The problem is that I repeat this try ... catch block in each method. I would like my API methods to be like:
public function getDouble($number) {
if (!is_numeric($number)) {
throw new HttpException(400, 'Invalid number.');
}
return $number;
}
And then, catch those exceptions and form JSON in another place. What is the best approach here in terms of good application architecture?
Response on Exception
You could do this by handling the exception in App\Exceptions\Handler.
You could do it in the render method, likeso :
/**
* Render an exception into an HTTP response.
*
* #param \Illuminate\Http\Request $request
* #param \Exception $e
* #return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
if($e instanceof HttpException) {
return response()->json($e->getMessage(), $e->getStatusCode());
}
return parent::render($request, $e);
}
Success Response
There are several ways to do this but I guess Middleware would be the best suited one right.
Create a middleware (say, ApiResponseFormatterMiddleware)
In your 'App\Http\Kernel', add it to $routeMiddleware array.
Apply it to the api routes, response to which you want to parse.
You could do something in the lines of :
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
$response = $next($request);
return response()->json($response->getOriginalContent());
}
Ofcourse, you need to change a bit of logic to parse the content the way you want it, but skeleton remains the same.