I've upgraded 2 laravel applications on 5.4 few months ago.
Those application were created on 5.1, and I've always follow the upgrade guide 1 month after any release publication.
Since 5.4, I often have this kind of error on POST request :
Illuminate\Contracts\Encryption\DecryptException·The payload is invalid
app/Http/Middleware/CheckForMaintenanceMode.php:43App\Http\Middleware\CheckForMaintenanceMode::handle
throw new HttpException(503);
}
return $next($request); //line 43
}}
Most of the time POST request are ok, but sometimes (around 1 POST request on 1000) I have this error. I fail to reproduce it.
Thanks
Make sure that the column that you are using to store the encrypted is long enough.
I got this same exception because my 64 encoded string was being strip down due to column length.
keep in mind that the size of the encrypted string can change depending on the size of the text passed through the encrypt function.
You need to be using the EncryptCookies middleware for the route your're accessing. Do you have the 'web' middleware group applied to your routes?
Your Http Kernel should have this in it:
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
'api' => [
'bindings',
],
];
Then you can apply 'web' to your routes/groups.
Related
Earlier i tried this approach stackoverflow post but it gives 419 issue on local
'api' => [
// do not resolve Session store not set on request issue register user
// \App\Http\Middleware\EncryptCookies::class,
// \Illuminate\Session\Middleware\StartSession::class,
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
So after following laravel docs. I came to know sanctum.php and figured out the exact issue. And remove those two lines from kernel.php
Solution:
Set APP_URL correctly in environment variables as being used to set stateful domains in /config/sanctum.php. If issue is on production use production domain.
'stateful' => explode(',', env('SANCTUM_STATEFUL_DOMAINS', sprintf(
'%s%s',
'localhost,localhost:3000,127.0.0.1,127.0.0.1:8000,::1',
env('APP_URL') ? ','.parse_url(env('APP_URL'), PHP_URL_HOST) : ''
))),
I want to ask how can you run the auth middleware before the model binding? Currently in my 5.7 application, model binding is run before the auth. I tried creating a middlwaregroup in kernel.php as follows:
'api' => [
'throttle:10,1',
'jwt.middleware',
'bindings',
],
But still the model binding is run before the auth. Also I tried to change the order of the two middlewares in my route but nothing changed.
The answer is in:
https://laravel.com/docs/5.7/middleware#sorting-middleware
protected $middlewarePriority = [
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\Authenticate::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\Auth\Middleware\Authorize::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
];
IF you use explicit bindings, they may run before the auth middleware. In that case, you can use Auth::authenticate() to throw an AuthenticationException which laravel will transform into a redirect to the login page.
Route::bind('user_post', fn ($id) => Auth::authenticate()->posts()->findOrFail($id));
Route::get('posts/{user_post}', ...);
I have added into the exceptions:
protected $except = [
'pay/finish'
];
But still I am getting MethodNotAllowedException
Route is defined in web.php
Route::post('/pay/finish', ['as' => 'pay.finish', 'uses' => 'PaymentController#finish']);
The post request comes from another domain.
You don't normally get a MethodNotAllowedException from an invalid CSRF token. I normally get a 419 response from CSRF issues.
However, assuming the CSRF token is the problem you could move your route from web.php to api.php. Be aware this adds the prefix api/ to the URL.
The middleware that checks the CSRF token is applied in your Kernel to all routes in web.php but not to those is api.php
You could verify whether the CSRF check is really the problem by looking in your App\Http\Kernel file and commenting out \App\Http\Middleware\VerifyCsrfToken::class from:
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\Laravel\Passport\Http\Middleware\CreateFreshApiToken::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
If your route then works it is CSRF and you can move the route to the API routes file and hit it at api/pay/finish with the api prefix.
If not then I suggest you look at what's calling your route and check the correct http method is being called. Is it definitely sending a POST request?
Do you have the _method input specified in your form that Laravel checks for POST requests to mutate them to PUT or PATCH for its edit routes?
I'm using the default Laravel 5.8 authentication model. It worked fine, but recently I noticed that after I enter the wrong credentials in the login form, it still redirects me to the homepage, and in the corner the browser asks me if I want to save password and etc. Everything looks like I was logged in, but I'm not.
If I enter the correct information, then I get logged in and everything works fine.
I was looking for a solution, but everything I could find was modifying LoginController and RegisterController, and I think I don't want to do that, because default behavior is what I need. So the problem must be somewhere else.
I don't know what code to show. My best guess of what could be related is:
web.php
Route::get('logout', 'Auth\LoginController#logout');
Auth::routes(['verify' => true]);
app/Http/Kernel.php middleware groups
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
// \Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
'admin' => [
\App\Http\Middleware\Administrator::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
What I expect: to be redirected back to the same page after an incorrect login/registration.
Problem was that I had this
<meta name=“referrer" content=“origin”>
in my html
I have two similiar Laravel project. This is part code of kernel.php. Both projects have same code.
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
],
'api' => [
'throttle:60,1',
],
];
But, VerifyCsrfToken always be called although I put my route inside api middlewareGroup.
I check request header in Advanced REST Client. I found this.
First project result :
Second project result :
First result has cookie attribute in request header, but second result doesn't have
You can skip csrf token check for all your api links in app/Http/Middleware/VerifyCsrfToken.php by adding the URIs to the $except property. Example:
protected $except = [
'/api/*'
];
All the routes in routes.php are included in a route group which has the 'web' middleware applied. You should probably create another routes file and have the RouteServiceProvider load those in a group with 'api' and without the 'web' middleware applied.
If you open up your RouteServiceProvider you will see where this is happening. Check the map method to see it calling mapWebRoutes.
Use routes without any middleware and it will not require csrf token anymore.