In my my laravel 5.7.3 application I use https://github.com/jrean/laravel-user-verification extention and with use of
middleware I generate UserNotVerifiedException error when logged is not verified
But with excception I want to make logout and redirect to /login page and reading https://laravel.com/docs/master/errors#the-exception-handler doc in
file app/Exceptions/Handler.php I do :
<?php
namespace App\Exceptions;
use Exception;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Auth;
use App\Exceptions\UserNotVerifiedException;
use Illuminate\Support\Facades\Redirect;
use Illuminate\Foundation\Auth\RegistersUsers;
use Jrean\UserVerification\Traits\VerifiesUsers; // Do I need to add these declarations here ?
use Jrean\UserVerification\Facades\UserVerification;
class Handler extends ExceptionHandler
{
use RegistersUsers;
use VerifiesUsers;
protected $dontReport = [
//
];
protected $dontFlash = [
'password',
'password_confirmation',
];
public function report(Exception $exception)
{
parent::report($exception);
}
public function render($request, Exception $exception)
{
dump($exception);
if ($exception instanceof UserNotVerifiedException) {
dump("Make Logout");
Auth::logout();
return redirect('/admin/dashboard/index');
}
return parent::render($request, $exception);
}
}
In dump file I see first message, but not second(and why there is no redirection):
UserNotVerifiedException {#509 ▼
#message: "This user is not verified."
#code: 0
#file: "/mnt/_work_sdb8/wwwroot/lar/Votes/vendor/jrean/laravel-user-verification/src/Middleware/IsVerified.php"
#line: 26
trace: {▶}
}
Which is valid way ?
Thanks!
You can try to put the original namespace like:
if ($exception instanceof \Jrean\UserVerification\Exceptions\UserNotVerifiedException) {
dump("Make Logout");
Auth::logout();
return redirect('/admin/dashboard/index');
}
Related
Working with laravel 8 app started by other developer, I can not show
file /resources/views/errors/404.blade.php(I have this file) when invalid url like
http://127.0.0.1:8000/app_admin/platforms/2/editINVALID URL
I got empty page with 200 Status Code returned
in routes/web.php I see :
<?php
use Illuminate\Support\Facades\Route;
...
/* ========= For Adminside ========= */
Route::group(array('middleware' => 'auth_admin', 'prefix' => 'app_admin'), function() {
...
In file app/Http/Middleware/AuthenticatedAdmin.php I have :
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class AuthenticatedAdmin
{
public function handle($request, Closure $next, $guard = null)
{
$uri = $request->path();
$bypass_uri = array('/app_admin', 'app_admin/login',
'app_admin/logout', 'app_admin/forgot_password');
if (!in_array($uri, $bypass_uri)) {
if (Auth::guard($guard)->check()) {
if (Auth::user()->urole == 1) {
// return redirect()->route('dashboard');
}
if (Auth::user()->urole == 0) {
return redirect()->url('/');
}
} else {
return redirect()->route('login');
}
}
return $next($request);
}
}
Also I try add logs into :
app/Exceptions/Handler.php :
<?php
namespace App\Exceptions;
//use Laravel\Fortify\Contracts\LogoutResponse;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Throwable;
class Handler extends ExceptionHandler
{
protected $dontReport = [
//
];
protected $dontFlash = [
'password',
'password_confirmation',
];
public function register()
{
$this->reportable(function (Throwable $e) {
\Log::info( varDump($e, ' -1 app/Exceptions/Handler.php register $e::') );
});
}
public function render($request, Throwable $e)
{
$response = parent::render($request, $e);
\Log::info( varDump($response->status(), ' -1 app/Exceptions/Handler.php render $response->status()::') );
if ($response->status() === 419) {
\Log::info( ' Expired' );
auth()->logout();
// return app(LogoutResponse::class);
}
if ($this->isHttpException($e)) {
if ($e->getStatusCode() == 404) {
return response()->view('errors' . '404', [], 404);
}
}
return $response;
}
}
I do not see any logs when I enter invalid url like :
http://127.0.0.1:8000/app_admin/platforms/2/editINVALID URL
How can it be fixed?
Thanks!
In my Laravel-8 application, I am trying to bind Repository to an Interface
I have this code:
App\Providers\RepositoryServiceProvider:
class RepositoryServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->bind(
'App\Interfaces\Auth\AuthInterface',
'App\Repositories\Auth\AuthRepository'
);
}
}
config\app:
App\Providers\RepositoryServiceProvider::class,
Then the interface looks like this:
namespace App\Interfaces\Auth;
use Illuminate\Http\Request;
use App\Http\Requests;
interface AuthInterface
{
public function register(Request $request);
}
Repository Implementation:
namespace App\Repositories\Auth;
use App\Interfaces\Auth\AuthInterface;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
use App\Traits\ApiResponse;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Password;
use Carbon\Carbon;
use Illuminate\Support\Facades\DB;
class AuthRepository implements AuthInterface
{
use ApiResponse;
public function register(DriverRequest $request)
{
DB::beginTransaction();
try {
$newUser = User::create([
'first_name' => $request->first_name,
'last_name' => $request->last_name,
'email' => preg_replace('/\s+/', '', strtolower($request->email)),
'password' => bcrypt($request->password)
]);
DB::commit();
return $this->success('Signup Successfully Done, please check your email to activate account', $newUser);
} catch(\Exception $e) {
DB::rollback();
Log::error($e);
return $this->error($e->getMessage(), $e->getCode());
}
}
}
Controller
use App\Interfaces\Auth\AuthInterface;
class AuthController extends Controller
{
protected $authInterface;
public function __construct(AuthInterface $auth)
{
$this->authInterface = $auth;
}
public function register(Request $request)
{
return $this->authInterface->register($request);
}
}
When I did php artisan route:list, I got this error:
Illuminate\Contracts\Container\BindingResolutionException
Target [App\Interfaces\Auth\AuthInterface] is not instantiable while building [App\Http\Controllers\Api\V1\Auth\AuthController].
at C:\xampp\htdocs\myapp\vendor\laravel\framework\src\Illuminate\Container\Container.php:1049
1045▕ } else {
1046▕ $message = "Target [$concrete] is not instantiable.";
1047▕ }
1048▕
➜ 1049▕ throw new BindingResolutionException($message);
1050▕ }
1051▕
1052▕ /**
1053▕ * Throw an exception for an unresolvable primitive.
1 C:\xampp\htdocs\myapp\vendor\laravel\framework\src\Illuminate\Container\Container.php:842
Illuminate\Container\Container::notInstantiable("App\Interfaces\Auth\AuthInterface")
2 C:\xampp\htdocs\myapp\vendor\laravel\framework\src\Illuminate\Container\Container.php:714
Illuminate\Container\Container::build("App\Interfaces\Auth\AuthInterface")
How do I get it resolved?
Thanks
It might be from your namespace, I had the same issue...it came from my namespace
I'm using larvel 8 and want to change message of "CSRF token mismatch" when using ajax post. I created a closure and passed it to the renderable method on the App\Exceptions\Handler class, but the previews message appears.
This is my code:
use Illuminate\Session\TokenMismatchException;
class Handler extends ExceptionHandler
{
protected $dontReport = [
//
];
protected $dontFlash = [
'password',
'password_confirmation',
];
public function register()
{
$this->renderable(function (TokenMismatchException $e, $request) {
return $request->expectsJson()
? response()->json(['message' => 'A new message...'], 419)
: redirect()->guest(route('login'));
});
}
To modify error message on TokenMismatchException both for web-pages and ajax-requests
It would be better to overload prepareException() method in application exception handler:
protected function prepareException(Exception $e)
{
if ($e instanceof TokenMismatchException) {
$e = new HttpException(419, __('exception.csrf_token_mismatch'), $e);
}
return parent::prepareException($e);
}
So you can create translation file and modify message by language files. For example create resources/lang/en/exception.php with content below:
<?php
return [
'csrf_token_mismatch' => 'CSRF token mismatch. Please, refresh page (CTRL+R) and try again.',
];
thanks to everyone who contributed, I found the solution.
Due to laravel change the TokenMismatchException to HttpException in the function prepareException in the Illuminate\Foundation\Exceptions\Handler class(parent of Handler class), we cannot render the TokenMismatchException.
protected function prepareException(Throwable $e)
{
if ($e instanceof ModelNotFoundException) {
$e = new NotFoundHttpException($e->getMessage(), $e);
} elseif ($e instanceof AuthorizationException) {
$e = new AccessDeniedHttpException($e->getMessage(), $e);
} elseif ($e instanceof TokenMismatchException) {
$e = new HttpException(419, $e->getMessage(), $e);
} elseif ($e instanceof SuspiciousOperationException) {
$e = new NotFoundHttpException('Bad hostname provided.', $e);
} elseif ($e instanceof RecordsNotFoundException) {
$e = new NotFoundHttpException('Not found.', $e);
}
return $e;
}
I modify my renderable method as below and now I can catch the TokenMismatchException:
$this->renderable(function (HttpException $e, $request) {
if ($e->getPrevious() instanceof TokenMismatchException) {
return $request->expectsJson()
? response()->json(['message' =>'Your new message ...', 419)
: redirect()->guest(route('login'));
}
});
If you want to change the error message or the page that is shown when CSRF token mismatch happen
Run this command: php artisan vendor:publish --tag=laravel-errors
It will publish your default (vendor) exceptions page to resources/views/errors/
From there, edit resources/views/errors/419.blade.php with html that you would like to show when CSRF verification error happen.
References: https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
419 Page Expired (Laravel Framework)
Used by the Laravel Framework when a CSRF Token is missing or expired.
If you want to allow ajax requests to bypass CSRF token verification
Reference: https://laravel.com/docs/8.x/csrf#csrf-excluding-uris
Edit your VerifyCsrfToken middleware (location: app/Http/Middleware/VerifyCsrfToken.php), add:
class VerifyCsrfToken extends Middleware
{
/**
* The URIs that should be excluded from CSRF verification.
*
* #var array
*/
protected $except = [
'stripe/*',
'http://example.com/foo/bar',
'http://example.com/foo/*',
];
}
How can I get the laravel 4 debugger page in laravel 5 debugger
page
here
to
Install the whoops package:
composer require filp/whoops
Then use it to render your exceptions by editing your app/Exceptions/Handler.php:
<?php namespace App\Exceptions;
use Exception;
use Whoops\Run as Whoops;
use Illuminate\Http\Response;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use PragmaRX\Sdk\Services\ExceptionHandler\Service\Facade as SdkExceptionHandler;
class Handler extends ExceptionHandler {
protected $dontReport = [
'Symfony\Component\HttpKernel\Exception\HttpException'
];
public function report(Exception $e)
{
return parent::report($e);
}
public function render($request, Exception $e)
{
if ($this->isHttpException($e))
{
return $this->renderHttpException($e);
}
if (env('APP_DEBUG'))
{
return $this->whoops($e);
}
return parent::render($request, $e);
}
protected function whoops(Exception $e)
{
$handled = with(new Whoops)
->pushHandler(new \Whoops\Handler\PrettyPageHandler())
->handleException($e);
return new Response(
$handled,
$e->getStatusCode(),
$e->getHeaders()
);
}
}
I'm starting out in Laravel and want to discover more about using error handling especially the ModelNotFoundException object.
<?php
class MenuController extends BaseController {
function f() {
try {
$menus = Menu::where('parent_id', '>', 100)->firstOrFail();
} catch (ModelNotFoundException $e) {
$message = 'Invalid parent_id.';
return Redirect::to('error')->with('message', $message);
}
return $menus;
}
}
?>
In my model:
<?php
use Illuminate\Database\Eloquent\ModelNotFoundException;
class Menu extends Eloquent {
protected $table = 'categories';
}
?>
Of course for my example there are no records in 'categories' that have a parent_id > 100 this is my unit test. So I'm expecting to do something with ModelNotFoundException.
If I run http://example.co.uk/f in my browser I receive:
Illuminate \ Database \ Eloquent \ ModelNotFoundException
No query results for model [Menu].
the laravel error page - which is expected, but how do I redirect to my route 'error' with the pre-defined message? i.e.
<?php
// error.blade.php
{{ $message }}
?>
If you could give me an example.
In Laravel by default there is an error handler declared in app/start/global.php which looks something like this:
App::error(function(Exception $exception, $code) {
Log::error($exception);
});
This handler basically catches every error if there are no other specific handler were declared. To declare a specific (only for one type of error) you may use something like following in your global.php file:
App::error(function(Illuminate\Database\Eloquent\ModelNotFoundException $exception) {
// Log the error
Log::error($exception);
// Redirect to error route with any message
return Redirect::to('error')->with('message', $exception->getMessage());
});
it's better to declare an error handler globally so you don't have to deal with it in every model/controller. To declare any specific error handler, remember to declare it after (bottom of it) the default error handler because error handlers propagates from most to specific to generic.
Read more about Errors & Logging.
Just use namespace
try {
$menus = Menu::where('parent_id', '>', 100)->firstOrFail();
}catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e) {
$message = 'Invalid parent_id.';
return Redirect::to('error')->with('message', $message);
}
Or refer it to an external name with an alias
use Illuminate\Database\Eloquent\ModelNotFoundException as ModelNotFoundException;
When you use the render() function in Laravel 8.x and higher versions, you will encounter 500 Internal Server Error. This is because with Laravel 8.x errors are checked within the register() function (Please check this link)
I'm leaving a working example here:
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
use Illuminate\Database\Eloquent\ModelNotFoundException;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Throwable;
class Handler extends ExceptionHandler
{
public function register()
{
$this->renderable(function (ModelNotFoundException $e, $request) {
return response()->json(['status' => 'failed', 'message' => 'Model not found'], 404);
});
$this->renderable(function (NotFoundHttpException $e, $request) {
return response()->json(['status' => 'failed', 'message' => 'Data not found'], 404);
});
}
}
Try this
try {
$user = User::findOrFail($request->input('user_id'));
} catch (ModelNotFoundException $exception) {
return back()->withError($exception->getMessage())->withInput();
}
And to show error, use this code in your blade file.
#if (session('error'))
<div class="alert alert-danger">{{ session('error') }}</div>
#endif
And of course use this top of your controller
use Illuminate\Database\Eloquent\ModelNotFoundException;