Laravel 5.5 Session getting lost on each request - php

When logging in, authentication works and the user is redirected to the logged-in page (/home at first but I also tried changing to /dashboard) but then the session seems to become lost as it shows an empty array when logging on the logged-in controller.
My setup involves using Redis as a session store but I have tried file and database drives as well with the same results.
Even stranger, I am able to view the session data in my redis cli without any issues.
Some "fixes" I have tried to no avail are:
- removing underscores from session cookie name (as well as dashes/hyphens)
- changing session domain setting to all combinations of main domain and subdomain
Does anyone have any ideas on any other possible fixes?
UPDATE:
Other fixes tried:
alternative session drivers (file, database, and cookie)
php artisan cache:clear
php artisan clear-compiled

Where did you write your Routes ?
Please note that the web middleware uses the default Laravel Session.
So routes written in routes/web.php are the ones using Laravel Session. You can also try using the file driver, but make sure the /storage folder has at 0755 permission.
also, can you please check you App\Providers\RouteServiceProviders mapWebRoutes() method looks like this?
/**
* Define the "web" routes for the application.
*
* These routes all receive session state, CSRF protection, etc.
*
* #return void
*/
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
Assuming you didn't modify the app\Http\Kernel.php

The problem resolved with me after remove \App\Http\Middleware\EncryptCookies::class from web inside $middlewareGroups in app\Http\Kernel.php file.

Related

Unable to list laravel routes because target class not found

I am currently working on an API only laravel application. In the controllers folder, there is an API folder that holds all controllers. The ForgotPasswordController is in the API folder as well.
When I run the command php artisan route:list I get the error below
Illuminate\Contracts\Container\BindingResolutionException : Target class [App\Http\Controllers\Auth\ForgotPasswordController] does not exist.
There is actually no ForgotPasswordController in the Auth folder. How do I handle this issue?
You have to make sure you are doing php artisan route:cache priority.
If the problem still persists, can you disable the auth provider and try?
For the sake of time considering that the project is live and I need to churn out a couple of features, I have moved both ForgotPassword and ResetPassword controllers back into the Auth folder. Ran a test to make sure nothing has been broken (everything works fine) and now I am able to list out the routes.
If you have Auth::routes() or Route::auth() in your routes file that would be generating routes to the ForgotPasswordController.
You would need to not be calling that or you would need to pass the proper option to it to have it not register those routes:
Auth::routes(['reset' => false]);
Depending on the version you are using this may not work. If that is the case you will have to not use this method at all and register the routes you want/need yourself.

Laravel Environment Variables(without default value passed in method) not working inside Artisan Command file

I am using Laravel 6.x for client's project wherein I have built an API in the Artisan Command for syncing data.
Now client wants the configuration to be discreet, out of main source code and without any fallback values as possible. That means I must define the configs in the .env file and use the env() method without any fallback default values.
This must be possible inside Laravel Artisan command class files, but it is not working as intended when I use the env method in the code as below:
[siteroot]\.env:
APP_ENV=local
[siteroot]\app\Console\Commands\SyncSomeData.php:
use Illuminate\Console\Command;
class SyncSomeData extends Command
{
/**
* The name and signature of the console command.
*
* #var string
*/
protected $signature = 'sync:some-data';
/**
* Create a new command instance.
*
* #return void
*/
public function __construct()
{
parent::__construct();
}
/**
* Execute the console command.
*
* #return mixed
*/
public function handle()
{
exit(env('APP_ENV','staging1'));
}
}
This always prints staging1 in console and if I use this instead of the given env method, then it prints nothing:
exit(env('APP_ENV'));
As I know and can trust that Laravel is most secure, there must be way to have env method work without fallback value in the command file, can anyone help fulfilling this ?
There are a couple parts to this answer.
Caching Config
The issue in this question is only present if you have cached your config on your local environment. If you have ever run php artisan config:cache or php artisan optimize, you have cached your config.
As a result, laravel will no longer read your .env file and load all values for config and .env from cache.
It is best practice, to not use env() throughout your application but create config files for these values. This will speed up your application in production. If you want to take advantage of config cache, you CAN NOT use env() anywhere but in your config files.
In your local environment, the documentation recommends you should not be caching your configuration, since it will be updated frequently. I think this is good advice with one caveat: env(). If you aren't caching your config on local, but are in production, you won't come across errors like the one that was the impetus for this post in local. If you have a ci pipeline and good testing practices than this hurdle is overcome.
If you stick with cache config in local, every time you update your config files or your .env file you will need to run php artisan config:cache.
Disabling config cache
By running php artisan config:clear or removing /bootstrap/cache/config.php laravel will no longer to attempt to read config from cache, and .env will work outside of config files. If you do this, as I stated in (1) make sure there is a part of your pipeline that will catch these errors, if you are caching config in production.
After more discussion with OP, I will make one more thing clear:
Cache config does not automatically just cache your .env keys so you can access them like config('SOME_CUSTOM_DOT_ENV_KEY'). When using cache config, if you need to access environment variables inside of your application, you must reference them in a config file.
Again, once config cache is enabled,.env becomes useless, but it is used to build the cache.
So if you in .env say:
GOOGLE_API_TOKEN=xxxx
You would maybe create a config file like:
google.php
return [
'api_token' => env('GOOGLE_API_TOKEN', 'some-default-value'),
];
And in your application, you will only reference config('google.api_token') and never env('GOOGLE_API_TOKEN').

Caching web routes with forced url in laravel

I'm running a laravel project behind a reversed proxy which is why I need to force the root url and scheme:
URL::forceRootUrl($proxy_url);
URL::forceScheme($proxy_schema);
I've added this to the top of my /routes/web.php and it's working fine until I run:
php artisan optimize
It caches the routes in /bootstrap/cache without the forced url and scheme, so now all my urls are pointing to the wrong root url.
I've tried to move the code to /Providers/AppServiceProvider.php (both register and boot) in order to make it take effect when caching the routes but no luck.
I have to manually delete the routes cache file in /bootstrap/cache to make my routes work again.
Have do I make it take effect when caching the routes?
Edit:
I have also tried to create a global middleware where I do the force url and schema. Again it works fine before caching the routes, but when running php artisan optimize the routes are once again incorrect.
php artisan optimize removed since laravel 5.6 (source, source2)
Using URL::forceRootUrl and URL::forceScheme seems like a work-around for working with reverse proxies. The clean solution for it would be to add a trusted proxies in your configuration. This post explains the feature in full. But it comes down to:
Use the App\Http\Middleware\TrustProxies middleware
Edit the middleware $proxies property with the IP(s) of your load balancer
protected $proxies = [
'192.168.1.1',
'192.168.1.2',
];
Remove the following code from /routes/web.php
URL::forceRootUrl($proxy_url);
URL::forceScheme($proxy_schema);

Laravel storage auth check

I have to download some files from my webapp with laravel 5.6 and I am using the local storage.
I have my routes like downloads/{file} with the auth middleware and it's working properly.
The storage url is the default from laravel www.myweb.com/storage/files/ ...
the thing is if I use the route www.myweb.com/downloads/foo.pdf the controller is working properly and i must be logged in to download the file
but if I access from www.myweb.com/storage/files/foo.pdf I can see the file without being logged in
How can i solve this? should i create another controller or route to handle this?
should i create a route like
Route::get('/storage/files/{file}', 'FilesController#download')->middleware('auth');
/storage/files is already actual path of the storage. to avoid conflict change your route to other path
Route::get('/storage/files/{file}', 'FilesController#download')->middleware('auth');
change to (sample)
Route::get('/files/{file}/download', 'FilesController#download')->middleware('auth');
then do your logic in FilesController

Laravel 5 - Cookies not present

I'm doing a laravel app but when I try to create an account it gives a csrf error..
When I check what cookies the website have, I find that I have no cookies, there should be a XSFR-TOKEN and a laravel_session cookies, but laravel is not generating any of those cookies, so it gives me a token not found when i try to create an account.. anyone know why it does that? any idea how to fix that?
Also just installed a new clean laravel and find out if I put the "app" view inside of a folder it also happends and doesnt generate the cookies, I have tried to change the folder permissions but the problem persists.
Open your http app/Http/Kernel.php file and check if your Kernel::$middleware array contains:
Illuminate\Cookie\Middleware\EncryptCookies
Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse
Illuminate\Session\Middleware\StartSession (this is middleware which is responsible for passing data to session driver in Laravel 5)
Illuminate\View\Middleware\ShareErrorsFromSession
App\Http\Middleware\VerifyCsrfToken
To clarify - Kernel::$middleware array contains middleware which is executed on every HTTP request. By default it contains middleware that is essential for session support in Laravel. Perhaphs you accidentaly deleted them.
Here is original file: https://github.com/laravel/laravel/blob/v5.0.22/app/Http/Kernel.php

Categories