I used to run debug true in production when needed with Laravel 5 the following way:
'debug' => env('APP_DEBUG', $_SERVER['REMOTE_ADDR'] == 'myipaddress' ? true : false),
However Laravel 6 doesn't let me use it, when I do artisan config:cache, artisan complains that:
variable $_server['REMOTE_ADDR'] is not defined and exists.
Is there another way someone has found out to be working to do this with Laravel 6?
You can't cache dynamic configs. there is no request and no $_server when Laravel tries to cache your configs.
You must disable your debug on production (APP_DEBUG = false) and check the log for any errors.
But if you insist to enable app debug dynamically, you can use middleware:
Create a new middleware using Artisan command:
php artisan make:middleware EnableDebug
This command will place a new EnableDebug class within your app/Http/Middleware directory. Modify it like this:
<?php
namespace App\Http\Middleware;
use Closure;
class EnableDebug
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
config(['app.debug' => $request->ip() === 'myipaddress']);
return $next($request);
}
}
List your middleware class at the end of the $middleware property of your app/Http/Kernel.php class:
protected $middleware = [
//...
\App\Http\Middleware\EnableDebug::class,
];
Related
Is there a way to make a route APP_DEBUG exclusive in Laravel 8?
I can set routes in the PreventRequestsDuringMaintenance middleware exception list.
But that is only for when maintenance mode is on.
I know I can simply do an abort(403) on a Route if Debug mode is on but I'm using Laravel Web Console library which communicates with it's own route when executing commands. So I need to strictly block any requests to that route when in Debug mode.
I want to block certain routes when not in Debug mode. Does Laravel come with such option or do I need a third party library?
As James suggested it, I tinkered with middlewares and registered a global middleware to abort 403 if any uri matches one from a blacklist.
protected $middleware = [
...
// allows blocking some requests when debug mode is off
\App\Http\Middleware\PreventRequestsDuringProduction::class,
];
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Route;
class PreventRequestsDuringProduction
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle(Request $request, Closure $next)
{
$blacklist = [
'console',
'laravelwebconsole/execute'
];
$uri = Route::getRoutes()->match($request)->uri;
if(\in_array($uri, $blacklist) && !env('APP_DEBUG')) {
abort(403);
}
return $next($request);
}
}
Just migrated my Laravel app from a local environment to a online development environment on a remote server. After this migration I am getting an error:
ReflectionException thrown with message "Class App\Http\MiddleWare\NotUser does not exist"
I've deleted the vendor folder, as well as composer.lock and ran composer update. Also cleared bootstrap/cache and also tried runningphp artisan config:clear.
Purged all cache/* files from storage. Whenever I attempt to log in to the dashboard, I receive the error that middleware does not exist.
app/Http/Middleware/NotUser.php
<?php
namespace App\Http\Middleware;
use Closure;
class NotUser
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
# This middleware prevents anyone who is not an admin from accessing given route or controller
# apply by using it in the constructor, $this->middleware('is.admin');
if ($request->user()->role->name === 'user') {
return back()->with('error', __('Access denied'));
}
return $next($request);
}
}
app/Http/Kernel.php
protected $routeMiddleware = [
...
'not.user' => \App\Http\MiddleWare\NotUser::class
];
routes/web.php
Route::group(['prefix' => 'admin', 'middleware' => ['not.user', 'auth']], function () { ... }
This works fine on locally hosted environment. I had no problems. After I switched to a development environment I started receiving this error and I have no idea what's causing this.
The namespace is case sensitive I believe, so change this:
protected $routeMiddleware = [
...
'not.user' => \App\Http\MiddleWare\NotUser::class
];
to this:
protected $routeMiddleware = [
...
'not.user' => \App\Http\Middleware\NotUser::class
];
Notice the capital W in Middleware.
i did a migration from Laravel 4.2 to 5.0, and reading another questions, i created a new Middleware on my app\http\middleware but, i don't know how implement this to my RouteServiceProvider.php
This is my BeforeMiddleware:
<?php namespace App\Http\Middleware;
use Closure;
class BeforeMiddleware {
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next)
{
return $next($request);
}
}
And on my RouteServiceProvider i got this
App::before(function($request)
{
//I think here need to be my code...
});
You need to register your middleware in the app/Http/Kernel.php file.
Here you will find 3 options:
protected $middleware = [..] <-- run on EVERY request
protected $middlewareGroups = ['web'=>...] <-- run on all web routes
protected $routeMiddleware = ['auth'...] <-- run on routes when defined
I had to deal with this same situation some time ago for a CRM, and the ideal approach is to migrate what you had within App::before() in Laravel 4.2 to a service provider in Laravel 5.0.
At first you can just use the boot() method located in the AppServiceProvider, in a way that you can test the waters.
From there you can opt to have a dedicated service provider just to hold this part, such as AppBeforeServiceProvider.
You have mentioned a migration to middleware, but that is actually for filters coming from Laravel 4.2.
I have a freshly set up Laravel 5 project with a working site on "/". When I try to run the provided feature test tests/Feature/ExampleTest.php with PHPUnit 5.7.21 I receive status code 500.
1) Tests\Feature\ExampleTest::testBasicTest
Expected status code 200 but received 500.
Failed asserting that false is true.
The test class is as provided.
<?php
namespace Tests\Feature;
use Tests\TestCase;
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class ExampleTest extends TestCase
{
/**
* A basic test example.
*
* #return void
*/
public function testBasicTest()
{
$response = $this->get('/');
$response->assertStatus(200);
}
}
The returned page as being part of $response states the following error.
ini_set(): Cannot change zlib.output_compression - headers already sent
I did not change any value in the provided PHPUnit config file.
In my middleware I use the compression to ensure a compressed output of the website.
<?php
namespace App\Http\Middleware;
use Closure;
class AfterMiddleware {
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, Closure $next) {
ini_set('zlib.output_compression', 'On');
return $next($request);
}
}
When I uncomment the ini_set line, all goes well. What can I do to enable compression and be able to run PHPUnit?
Thanks a lot for your help in advance.
Set your ini_set('zlib.output_compression', 'On'); Edit the php.ini file , then it will be available globaly your application.
zlib.output_compression = On
If you use php --ini you will get list of used ini files and its path used
In my project, I am using Laravel purely as a backend api and all frontend is handled by Angular javascript. At the moment, the Laravel routes can be accessed directly and it will cough out all the data in Json that shows in the browser. I want to put a restriction on it so Laravel only responds to Ajax requests and nothing else.
I read this post here which has a solution for Laravel 4 that is by adding a restriction in filter.php. But as of Laravel 5.1, filters are no longer used and I believe Middleware can be used to do the same. However, I am not sure how to go ahead changing the Laravel 4 solution in that SO answer from filter to Middleware.
Can someone share your ideas on how to prevent Laravel 5.1 routes from being accessed directly please?
Laravel 4 solution using filter.php:
In filter.php declare this filter:
Route::filter('isAJAX', function()
{
if (!Request::AJAX()) return Redirect::to('/')->with(array('route' => Request::path()));
});
Then put all your routes that you only want accessible via AJAX into a group. In your routes.php:
Route::group(array('before' => 'isAJAX'), function()
{
Route::get('contacts/{name}', ContactController#index); // Or however you declared your route
... // More routes
});
Create the middleware file app/Http/Middleware/OnlyAjax.php with this content:
<?php
namespace App\Http\Middleware;
class OnlyAjax
{
/**
* Handle an incoming request.
*
* #param \Illuminate\Http\Request $request
* #param \Closure $next
* #return mixed
*/
public function handle($request, \Closure $next)
{
if ( ! $request->ajax())
return response('Forbidden.', 403);
return $next($request);
}
}
Then register your middleware in the file app/Http/Kernel.php
<?php namespace App\Http;
use Illuminate\Foundation\Http\Kernel as HttpKernel;
class Kernel extends HttpKernel
{
/**
* The application's global HTTP middleware stack.
*
* #var array
*/
protected $middleware = [
//... your original code
];
/**
* The application's route middleware.
*
* #var array
*/
protected $routeMiddleware = [
//... your original code
'ajax' => \App\Http\Middleware\OnlyAjax::class,
];
}
And finally attach the middleware to any route or group of routes you want to make only accessible via AJAX. i.e:
/// File: routes/web.php
// Single route
Route::any('foo', 'FooController#doSomething')->middleware('ajax');
// Route group
Route::middleware(['ajax'])->group(function () {
// ...
});