I've got the following issue: Whenever I make a single request towards Laravel the same session is used, whenever I make multiple Ajax requests then Laravel keeps creating new sessions.
I applied the StartSession and EncryptCookies middlewares on the API routes. My Kernel looks the following way:
'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,
],
'api' => [
\App\Http\Middleware\EncryptCookies::class,
'bindings',
AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
],
Does any one have an idea why multiple new sessions are created when in practice the session cookie should get renewed about the already created session.
Http apps are stateless meaning you Sessions are manually handled for multi request.
Clean all session data
$request->session()->flush();
Generate a new session id
$request->session()->regenerate();
Latavel is not a framework that expects
AddQueuedCookiesToResponse::class
Should be:
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class
Here's my Kernel middlewareGroups for reference
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,
],
'api' => [
'throttle:60,1',
\App\Http\Middleware\EncryptCookies::class,
'bindings',
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
],
];
Related
hello i am new at laravel and i build an eCommerce platform (details aren't important)
anyway my problem is i created a route that can catch all event from paypal webhook but when i directly access to it it's working but when i try from paypal webhook Simulator or even if did a sandbox payment didn't go through
i know the problem is from csrf verification and i tried excluding the route but didn't work and also tried creating a new RouteServiceProvider
here is my code in the Controller so i can catch anything from the request
$headers = getallheaders();
file_put_contents("/home/username/public_html/test.txt", json_encode($headers));
here is my route
Route::domain(env("APP_DOMAIN"))->group(function () {
Route::get('/paypal/n', 'HomeController#notifications');
});
i used domain(env("APP_DOMAIN")) because everyone can add his own domain and i want this to work just in the main domain .
the code in the RouteServiceProvider
public function map()
{
$this->mapApiRoutes();
$this->mapWebRoutes();
$this->mapPaymentRoutes();
//
}
protected function mapPaymentRoutes()
{
Route::middleware('payment')
->namespace($this->namespace)
->group(base_path('routes/payment.php'));
}
and of course i did define the payment middleware in the file Kernel.php and comment the VerifyCsrfToken class
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,
],
'payment' => [
\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,
],
'api' => [
'throttle:60,1',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
];
and even with all this and like a lot of test i couldn't get it to work
if i send a request to a pure php file it's working fine.
can you please help me with this i tried to find a solution in my own but it takes me like 15 days without any luck
i use laravel 6 .
in case someone else is struggling with this problem i had to do a work a round by creating a pure php file in public and send webhook request to that file url/file.php and the file catch data and send it to a command i created inside laravel to process it, so that everything that has anything to do with database is inside laravel and the file.php is just like a pipe .
i know it's not the best idea but it's not the worst either
and thanks for everyone who tried to help me .
I'm trying to get my sessions working for API-Routes. On Web-Routes everything is fine, but the Moment I try to use it on API-Routes the Session is empty.
I know APIs should be stateless but I just communicate with an external API and my Laravel instance is just the frontend.
So my authentification is just a simple Session::put('userData', $response->data); after the successful request to the login endpoint of the API. In there some data about name, email, some default data and the auth token for the user.
The last one is important because I'd like to access some endpoints via AJAX (axios) and I need to send the saved auth token to the API to get things working. But everything is broken at the moment I try to guard the API-Routes with my RedirectIfUnauthenticated-Middleware. It always redirects me to the login page, because the session is empty.
If I remove it, I get to the Controller but the session is still empty and I can't add the auth token to the api request.
I think I do something fundamentally wrong here. So maybe someone can help here.
I already tried to add \Illuminate\Session\Middleware\StartSession::class, to the $middlewareGroups api section, but it seems to reset all session data so I get logged out. But maybe I do something wrong here too.
It's anti-pattern but you can use sessions in Laravel API. Head to /app/Http/Kernel.php and add the following code:
'api' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Session\Middleware\StartSession::class,
'throttle:60,1',
'bindings',
...
];
It's important after you've done this to clear all your active sessions from session driver storage (whether it's files, database, memcache, etc). For sessions stored on files go to /storage/framework/sessions and remove all files except .gitignore.
Now Sessions should work for API routes as well.
To avoid redirection, make sure you add Accept : application/json to the request headers.
You can try and use laravel\sanctum (now included in a Laravel installation) and the EnsureFrontendRequestsAreStateful middleware by adding it to the api middleware groups in App\Http\Kernel
'api' => [
\Laravel\Sanctum\Http\Middleware\EnsureFrontendRequestsAreStateful::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
go to /app/Http/Kernel.php and add the following code:
'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
],
'api' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
I have a simple application and I want to be able to change language.
In my main controller I have:
session(['applocale' => 'en']);
$request->session()->put('applocale','en');
I know that these two lines are the same but I want to be sure that they both does not work.
Then I have API method:
public function switchLang(Request $request, $lang)
{
error_log("Current language is: " . session('applocale'));
error_log("Current language is: " . $request->session()->get('applocale'));
}
And here error_log shows nothing.
I'm following this thread: Laravel 5.3 - How to add Sessions to API without CSRF?
And in Debugbar I can see that my API function has hit middleware 'sessions' but session variables are not there.
That's how it's look like my 'seasons' middleware:
'sessions' => [
\Illuminate\Session\Middleware\StartSession::class,
]
It actually hits both 'api' and 'sessions' middleware.
Any ideas what I'm doing wrong?
This works for me (Laravel-5.7 ).
Firstly change the api middleware group to -
'api' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
'throttle:60,1',
'bindings',
],
in App\http\kernel.php .
Reference here.
Good afternoon guys, I'm having an issue I don't know if you have the same trouble, I upgrade my Laravel project and now all routes like this
Route::get('detail/client/{client}', "controller#method")
are breaking everything because the object instanced in the controller comes empty...
public function detail(FileRequest $request, Client $client){
dd($client) // empty object
}
If someone can help me with this please. If I remove the Client model and make the dd then return the ID of the object i.e "594"
You haven't written base Laravel version you are upgrading from, but I think it might have something in common with \Illuminate\Routing\Middleware\SubstituteBindings::class middleware.
Make sure you have it in middlwareGroups like this:
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, // <- this is the line you should have
],
'api' => [
'throttle:60,1',
'bindings',
],
];
in app/Http/Kernel.php file
and also make sure the routes you have problem are in web middleware group.
Im trying to build an api, and for some reason I need sessions. But if I include web middleware I get CSRF errors, and if I dont I cant have session started.
How to solve this?
go to app/Http/Kernel.php and add your own name like 'sessions' to the $middlewareGroups. It should contain \Illuminate\Session\Middleware\StartSession::class,
Assign 'sessions' to those routes you want.
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',
],
'sessions' => [
\Illuminate\Session\Middleware\StartSession::class,
]
];
routes/api.php
Route::group(['middleware' => ['sessions']], function () {
Route::resource(...);
});
Well, i killed like 2-3 hours to solve this problem and write checker on python to configure that problem is not in me.
However, lets talk about laravel API and how does it works.
By default laravel API works only with "tokens". If you want to use this ability, you should think about this 2 variants:
You can install "passport" (That's like a manager for your sessions but without session. Insted of em). Like: php artisan passport:install.
You can create column in your database, generate tokens and push em here.
But that's not what are we talking about here, right? Lets talk about really nice solution, that works fine for all verions of laravel.
There is a files, called Kernel.php. They are created for configure your application. By default all API routes will work with this rule:
'api' => [
'throttle:api',
\Illuminate\Routing\Middleware\SubstituteBindings::class,
],
If you want, you can check what is this Middleware about.
So, next step is to recreate 'api' rule.
What do you want to API do? Validate all with session? Validate all with CSRF or without it? Just watch here:
'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,
],
This is config of WEB routes. You can see there some interesting middlewares such:
\App\Http\Middleware\VerifyCsrfToken::class. Now you see, right?
Fixes for your API should looks like:
'api' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Session\Middleware\StartSession::class,
'throttle:api',
],
And if you want with CSRF:
'api' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Session\Middleware\StartSession::class,
App\Http\Middleware\VerifyCsrfToken::class,
'throttle:api',
],
By default base rules (guards) that controll your actions is created at config\auth.php and looks like (for api and web):
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
],
If you want if the future not to have any problems with this API, you should change this 'rules' in a same way:
'api' => [
'driver' => 'session',
'provider' => 'users',
],
And please, dont forget to CLEAR all, except of .gitignore here: /storage/framework/sessions
Happy coding! :)
To fix for Laravel 6.x, you can use the solution here
Open app\kernel.php
add \Illuminate\Session\Middleware\StartSession::class,
into 'api' => [ 'throttle:60,1', 'bindings', ],
Final outcome will be like this below:
'api' => [
\Illuminate\Session\Middleware\StartSession::class,
'throttle:60,1',
'bindings',
],
When you check your api response, you will see the cookie set in the header.
I got the solution here >> https://laravel.io/forum/laravel-api-using-session-issue
It actually solved it perfectly for me.