Laravel - access session variables in API - php

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.

Related

Laravel not receiving paypal webhook events

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 .

How to get sessions working in Laravel api routes?

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,
],

Laravel 5.5 empty object

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.

Building a call API project with laravel

I would like to build a call API laravel project, separate the front-end and back-end, but how?
All the API are writing in the routes/api.php, but the job that return a view still live in routes/web.php ,
is that normal ? if not, what should I do ?
The code like ...
routes/web.php:
Route::get('/book/{id}',function(){ return view('book.show')->with('id',$id) ;});
show.blade.php:
...
$(function(){
$.ajax{
url: 'api/book/{{ $id }}',
....
}
});
...
routes/api.php:
//return the book data that id = {id}
Route::get('/book/{id}','BookController#show');
You are using it correctly.
One of the benefits of separating web and api routes is you have more granular control over applying middlewares.
Take a look at app/Kernel.php file:
/**
* The application's route middleware groups.
*
* #var array
*/
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' => [
'throttle:60,1',
'bindings',
],
];
As #angad-dubey mentioned its good practise to separate them out so that the web deals with the front end and the api routes for ... Api calls.
I tend to separate mine further by adding an admin.php within the routes folder, so that my backend routes are also separated, Thus you don't have one file with a long list of routes to search through, and this way as shown above you can append different middleware to them and not to the others, which could cause issues in the long term

Why is the csrf token checked when i use api middelware

i am using laravel 5.2 whit the predefined middelwares 'api' and 'web'. in the kernel file its stated that web would use quite some while api only checks throttle:
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',
],
];
in my routes i grouped the api routes and applied only 'api'
Route::group(array('prefix' => 'api', 'middleware' => ['api']), function(){
Route::post('test', 'TestController#testfunction');
}); // End of api Group
but when i send a post to /api/test it throws the crsf token mismatch. if i put the 'api/test' to the exception in the VerifyCsrftoken.php it works again. i cant figure out why the crsf token gets checked if not defined as a middelware for the route. Does anyone has an idea why?
CSRF is a "middleware" registered globally in App\Http\Kernel.php. Removing it will default to no CSRF protection (Laravel4 behavior).
To enable it in a route:
Create a short-hand key in your
app/Providers/RouteServiceProvider.php:
protected $middleware = [
// ....
'csrf' => 'Illuminate\Foundation\Http\Middleware\VerifyCsrfToken',
];
You can now enable it to any Route:
$router->post('url', ['middleware' => 'csrf', function() {
...
}]);
Not really elegant but may be a spot on on your question, try it.

Categories