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,
],
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 am trying to create a session in PagesController > designQuote function. The Laravel call to session works but the session does not persist. Here is the code.
Session::push('design_quote_uploads.files', ["Hello"]);
print_r(Session::all());
This works first time but when I comment out the first line design_quote_uploads does not exist in the session vars in the next page load.
The config/Session.php settings is
'driver' => env('SESSION_DRIVER', 'file'),
After reading doc and another answer here I checked the Routes and Middleware and it looks like this:
In the web.php the call is:
Route::any('design-quote', 'PageController#designQuote');
The middlewareGroups in Kernel.php:
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,
],
];
If I place session_start(); at the top of designQuote method the session persists. Do I have to keep it there?
Edit: (I swear) Placing session_start() worked yesterday but it is not working today :(
Also the session file at storage/framework/sessions is updated fine every time. I.e. It has data when it is written and misses data when I refresh the page.
I don't know what is missing out there. I checked another answer but I didn't understand it fully. It seems like quite old as well. Any help is appreciate.
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.
I am using laravel 5.2 and I have problems with working with larvel sessions.
I am trying to get session id using Session::getId() in laravel but every time I refresh the page I get a diffrent value. I commented the EncryptCookies::class middleware it worked fine.
In config\session.php I change the domain to my site domain ddev.dev and the path is set to '\'.
[EDIT]
In SessionHandler::class middleware I echo the session id.
here is my app\Http\kernel.php:
protected $middleware = [
\Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
\Dideo\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\Dideo\Http\Middleware\VerifyCsrfToken::class,
\Dideo\Http\Middleware\GlobalConfig::class,
\Dideo\Http\Middleware\SessionHandler::class,
];