Skip to content

Instantly share code, notes, and snippets.

@tad3j
Created December 11, 2016 16:00
Show Gist options
  • Save tad3j/89a5cfed332bd5b66614cba706248067 to your computer and use it in GitHub Desktop.
Save tad3j/89a5cfed332bd5b66614cba706248067 to your computer and use it in GitHub Desktop.
Redirect guests to login page in case of 404
<?php
namespace App\Exceptions;
//use Auth;
use Exception;
use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Auth\AuthenticationException;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Session\TokenMismatchException;
use Illuminate\Validation\ValidationException;
use Symfony\Component\HttpKernel\Exception\HttpException;
use Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Illuminate\Auth\Middleware\Authenticate;
use Illuminate\Contracts\Container\Container;
class Handler extends ExceptionHandler
{
/**
* @var Authenticate
*/
private $authenticate;
public function __construct(Container $container, Authenticate $authenticate)
{
parent::__construct($container);
$this->authenticate = $authenticate;
}
/**
* A list of the exception types that should not be reported.
*
* @var array
*/
protected $dontReport = [
AuthenticationException::class,
AuthorizationException::class,
HttpException::class,
ModelNotFoundException::class,
TokenMismatchException::class,
ValidationException::class,
];
/**
* Report or log an exception.
*
* This is a great spot to send exceptions to Sentry, Bugsnag, etc.
*
* @param \Exception $exception
* @return void
*/
public function report(Exception $exception)
{
parent::report($exception);
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception|\Symfony\Component\HttpKernel\Exception\HttpException $e
* @return \Illuminate\Http\Response
*/
public function render($request, Exception $e)
{
// If the request wants JSON (AJAX doesn't always want JSON)
if ($request->wantsJson()) {
return $this->jsonExceptionResponse($request, $e);
}
$guest = true;
try{
$this->authenticate->handle($request, function () {}, []);
$guest = false;
} catch (Exception $e){
}
//redirect to login page in case user is not logged in and he gets a 404 or 405 exception
//TODO: Auth facade doesn't work, so logged in users also get redirected to log in page
if ($guest && ( $e instanceof MethodNotAllowedHttpException || $e instanceof NotFoundHttpException)) {
// if ($e instanceof MethodNotAllowedHttpException || $e instanceof NotFoundHttpException) {
return redirect('/login');
}
return parent::render($request, $e);
}
/**
* Convert an authentication exception into an unauthenticated response.
*
* @param \Illuminate\Http\Request $request
* @param AuthenticationException $exception
* @return \Illuminate\Http\Response
*/
protected function unauthenticated($request, AuthenticationException $exception)
{
if ($request->expectsJson()) {
return response()->json(['error' => 'Unauthenticated.'], 401);
}
return redirect()->guest('login');
}
/**
* Render an exception into an HTTP response.
*
* @param \Illuminate\Http\Request $request
* @param \Exception|\Symfony\Component\HttpKernel\Exception\HttpException $exception
* @return \Illuminate\Http\JsonResponse
*/
private function jsonExceptionResponse($request, Exception $exception)
{
//return custom JSON response for invalid CSRF token
if ($exception instanceof TokenMismatchException) {
return response()->json([
'error' => [
'exception' => 'TokenMismatchException',
'message' => 'Invalid CSRF token/session has expired.'
]
], 400); //status code
} elseif ($exception instanceof ValidationException) {
//for API we return a different format
if ($request->is('api/v*')) {
return response()->json([
'success' => 'false',
'message' => $exception->getMessage(),
'errors' => $exception->validator->getMessageBag()->toArray()
], 422);
}
//this just renders normal exception/validation messages
return parent::render($request, $exception);
}
// Define the response
$response = ['error' => 'Whoops, looks like something went wrong.'];
// If the app is in debug mode
if (config('app.debug')) {
// Add the exception class name, message and stack trace to response
$eClass = get_class($exception); //Reflection might be better here
$response['exception'] = $eClass . ' in ' . $exception->getFile() . ' line ' . $exception->getLine();
$response['message'] = $exception->getMessage();
$response['trace'] = $exception->getTrace();
}
// Default response of 400
$status = 400;
// If this exception is an instance of HttpException
if ($this->isHttpException($exception)) {
// Grab the HTTP status code from the Exception
$status = $exception->getCode() ?: $exception->getStatusCode();
}
// Return a JSON response with the response array and status code
return response()->json($response, $status);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment