F
Filament8mo ago
Stitch

Having issues grabbing user_id using auth-guard:web

I'm using FIlamentPHP v3 and I'm having issues fetching the authenticated/logged in user_id in my OrderController, I'm using $userId = Auth::id(); fasacde but for some reason it's not letting me grab the authenticated user_id. I'm using the default authentication method that comes with Filament not sanctum etc, I'm protecting the route with auth-guard:web middle-wear which FilamentPHP uses by default. Is there something obvious that someone can see I'm doing wrong?
28 Replies
Majid Al Zariey
Majid Al Zariey8mo ago
What are you using the Controller for? Or from where are you requesting the controller
Stitch
StitchOP8mo ago
The controller is used to store the user order and fetch details from a external API to store to the DB, everything up until that point is fine as evidenced by the logging I've done in laravel.log, except for grabbing the correct user_id that made the order. I'm requesting the controller from my Order.php page in app/Filament/pages/Orders.php
Majid Al Zariey
Majid Al Zariey8mo ago
could you share your api setup in web.php
Stitch
StitchOP8mo ago
My web.php is as follows <?php use Illuminate\Support\Facades\Route; Route::get('/', function () { return view('welcome'); }); My api.php is as follows <?php use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; use App\Http\Controllers\UserOrderController; Route::get('/user', function (Request $request) { return $request->user(); })->middleware('auth:web'); Route::post('/orders/new', [UserOrderController::class, 'store']);
Majid Al Zariey
Majid Al Zariey8mo ago
You are not applying the auth middleware to the order api
Stitch
StitchOP8mo ago
My bad, just applied this to routes/api.php "<?php use Illuminate\Http\Request; use Illuminate\Support\Facades\Route; use App\Http\Controllers\UserOrderController; Route::get('/user', function (Request $request) { return $request->user(); })->middleware('auth:web'); Route::post('/orders/new', [UserOrderController::class, 'store'])->middleware('auth:web');" But now I'm getting this error, I remember now I removed the middlewear to debug the process up untill fetching the user_id, which is now all going correct apart from fetching the user_id "[2024-04-14 20:18:58] local.ERROR: Route [login] not defined. {"exception":"[object] (Symfony\Component\Routing\Exception\RouteNotFoundException(code: 0): Route [login] not defined. at /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/UrlGenerator.php:477) [stacktrace]"
Majid Al Zariey
Majid Al Zariey8mo ago
are you using sanctum?
Stitch
StitchOP8mo ago
Not using sanctum, just what has come by default with FilamentPHP which I believe is auth-guard:web
Majid Al Zariey
Majid Al Zariey8mo ago
use this in web.php Route::redirect('/login', '/admin/login')->name('login');
Stitch
StitchOP8mo ago
Replace routes in web.php with what you sent but still getting this issue for some reason [2024-04-14 21:26:28] local.ERROR: Route [login] not defined. {"exception":"[object] (Symfony\Component\Routing\Exception\RouteNotFoundException(code: 0): Route [login] not defined. at /var/www/html/vendor/laravel/framework/src/Illuminate/Routing/UrlGenerator.php:477) [stacktrace]
Majid Al Zariey
Majid Al Zariey8mo ago
what do you get when php artisan route:list
Stitch
StitchOP8mo ago
ddev php artisan route:list ─╯ POST _ignition/execute-solution ignition.executeSolution › Spatie… GET|HEAD _ignition/health-check ignition.healthCheck › Spatie\LaravelI… POST _ignition/update-config ignition.updateConfig › Spatie\Larave… POST api/orders/new ..................... UserOrderController@store GET|HEAD api/user ..................................................... GET|HEAD filament/exports/{export}/download filament.exports.download … GET|HEAD filament/imports/{import}/failed-rows/download filament.impor… GET|HEAD livewire/livewire.js Livewire\Mechanisms › FrontendAssets@ret… GET|HEAD livewire/livewire.min.js.map Livewire\Mechanisms › FrontendAs… GET|HEAD livewire/preview-file/{filename} livewire.preview-file › Live… POST livewire/update livewire.update › Livewire\Mechanisms › Handl… POST livewire/upload-file livewire.upload-file › Livewire\Features… ANY login ........ login › Illuminate\Routing › RedirectController GET|HEAD sMS filament.sMS.pages.dashboard › Filament\Pages › Dashboard GET|HEAD sMS/deposits-page filament.sMS.pages.deposits-page › App\Fila… GET|HEAD sMS/login ... filament.sMS.auth.login › Filament\Pages › Login POST sMS/logout filament.sMS.auth.logout › Filament\Http › LogoutC… GET|HEAD sMS/orders filament.sMS.pages.orders › App\Filament\Pages\Ord… GET|HEAD sMS/recent-logins filament.sMS.pages.recent-logins › App\Fila… GET|HEAD sanctum/csrf-cookie sanctum.csrf-cookie › Laravel\Sanctum › C… GET|HEAD up ........................................................... Showing [21] routes
Majid Al Zariey
Majid Al Zariey8mo ago
could you share the redirect route in web.php
Stitch
StitchOP8mo ago
<?php use Illuminate\Support\Facades\Route; Route::redirect('/login', '/admin/login')->name('login'); I tried inserting /sMS/login and that didn't work either
Majid Al Zariey
Majid Al Zariey8mo ago
in your case it should be
Route::redirect('/login', '/sMS/login')->name('login');
Route::redirect('/login', '/sMS/login')->name('login');
Could you share your panel config middleware and the first part and please share the snippet that is requesting the API By the way are you using Laravel 11?
Stitch
StitchOP8mo ago
I think this may have been the fix, now it seems to be passing the user_id from app/Fillament/Pages/Orders.php to the controller according to the logging. Ideally it's more secure to pull the user_id in the controller though instead of the fillament page passing it to the controller though right? And yes I'm also using Laravel 11, thank you for your help so far with this
Majid Al Zariey
Majid Al Zariey8mo ago
What you are trying to do is accessing the same session with API , which is possible. You would need to change the group middleware for the api group Or you could use tokens to authenticate the api (more secure) But while you are using Livewire. Why are you using a controller. You could just include a function in Livewire
Stitch
StitchOP8mo ago
Tokens might be the way to go since each user will be having their own API token anyway to access the public API the service I'm building will have. I was looking to integrate this once I had the order controller built https://github.com/jeffgreco13/filament-breezy to make it easy to integrate the necessary features. Do you think it's worth integrating it now so that I can switch the whole authentication system over to sanctum for both the site and the public API? Also I'm quite new to Laravel and have only just mostly got my head around using controllers etc, haven't really got around to learning livewire yet
GitHub
GitHub - jeffgreco13/filament-breezy
Contribute to jeffgreco13/filament-breezy development by creating an account on GitHub.
Majid Al Zariey
Majid Al Zariey8mo ago
Breezy would give you multi-factor-auth ability, which I assume you dont need at the moment. Sanctum is easy to install and use. would take couple of mins to install But while you are in the same app, you dont need to request it externally, you could use the following in Liveware
app(Conroller::class)->requestFunctionName()
app(Conroller::class)->requestFunctionName()
Exactly where are you requesting the controller from. Inside Filament or a simple blade?
Stitch
StitchOP8mo ago
Inside Filament in the Pages folder, and if the Orders.php from the page folder is able to now pull the user_id, I don't see why I shouldn't be able to get the controller to do it instead. Currently looking into livewire though if you think that's a better approach
Majid Al Zariey
Majid Al Zariey8mo ago
Your Orders.php file is a livewire file through Just create a function and access it using wire:click if its a button. or after you complete your order in the save function for example
Stitch
StitchOP8mo ago
Ah, I thought all livewire file types were stored in views/livewire and were blade files though?
Majid Al Zariey
Majid Al Zariey8mo ago
Filament is built on Livewire. And Livewire is the bridge connecting betwwen the blade and php files. Share with me your code that is requesting the Controller. to show you how would you convert it to a livewire approach
Stitch
StitchOP8mo ago
This is the Test API button using Filament actions I made in app/Filament/Pages/Orders.php
protected function getHeaderActions(): array
{
return [
Actions\Action::make('testApiCall')
->label('Test API Call')
->action(function () {
// Log the request sent to the controller
Log::info('Request sent to the controller', [
'service' => $this->service,
'country' => $this->country,
'operator' => $this->operator,
'user_id' => Auth::id(),
]);

$response = Http::post('https://sms.ddev.site/api/orders/new', [
'service' => 'Netflix',
'country' => 'United Kingdom',
'operator' => 'Vodafone',
'user_id' => Auth::id(), // Pass the authenticated user's ID
]);

if ($response->successful()) {
Notification::make()
->title('API call successful.')
->success()
->send();
} else {
Notification::make()
->title('API call failed.')
->danger()
->send();
}
}),
];
}
protected function getHeaderActions(): array
{
return [
Actions\Action::make('testApiCall')
->label('Test API Call')
->action(function () {
// Log the request sent to the controller
Log::info('Request sent to the controller', [
'service' => $this->service,
'country' => $this->country,
'operator' => $this->operator,
'user_id' => Auth::id(),
]);

$response = Http::post('https://sms.ddev.site/api/orders/new', [
'service' => 'Netflix',
'country' => 'United Kingdom',
'operator' => 'Vodafone',
'user_id' => Auth::id(), // Pass the authenticated user's ID
]);

if ($response->successful()) {
Notification::make()
->title('API call successful.')
->success()
->send();
} else {
Notification::make()
->title('API call failed.')
->danger()
->send();
}
}),
];
}
It is currently working fine, but from learning laravel atm it seems best to pull the user_id from the controller, but if you think livewire is a better way I'd like to hear it
Majid Al Zariey
Majid Al Zariey8mo ago
$myRequest = new Request();
$myRequest->request->add([
'service' => 'Netflix',
'country' => 'United Kingdom',
'operator' => 'Vodafone'
]);
$result = app(UserController::class)->store(new Request($myRequest));
$myRequest = new Request();
$myRequest->request->add([
'service' => 'Netflix',
'country' => 'United Kingdom',
'operator' => 'Vodafone'
]);
$result = app(UserController::class)->store(new Request($myRequest));
Something like this Only for the case you need the controller for other Public API activities and I have been playing around and you could change the api guard to use sessions using config/auth.php
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'session',
'provider' => 'users',
],
],
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'session',
'provider' => 'users',
],
],
and in bootstrap/app.php
->withMiddleware(function (Middleware $middleware) {
$middleware->api([
EncryptCookies::class,
StartSession::class,

])->priority([
ForceJson::class,
EncryptCookies::class,
StartSession::class,

]);
})
->withMiddleware(function (Middleware $middleware) {
$middleware->api([
EncryptCookies::class,
StartSession::class,

])->priority([
ForceJson::class,
EncryptCookies::class,
StartSession::class,

]);
})
You could use a middleware ForceJson
class ForceJson
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
$request->headers->set('Accept', 'application/json');

return $next($request);
}
}
class ForceJson
{
/**
* Handle an incoming request.
*
* @param \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response) $next
*/
public function handle(Request $request, Closure $next): Response
{
$request->headers->set('Accept', 'application/json');

return $next($request);
}
}
or add the header to the request Then adding to the API
->middleware(['auth:web'])
->middleware(['auth:web'])
Would not recommend this approach if you are using the API publicly and internally
Stitch
StitchOP8mo ago
Hey nice, that's interesting. What approach would you use personally do you think, if you were to have a public API and have the user accessible site. Sanctum is looking like the best way to handle both tokens for logged in user sessions on the site and API tokens for the public API for each user I guess if I used Sanctum for both, it would avoid using multiple authentication methods to
Majid Al Zariey
Majid Al Zariey8mo ago
I would use Sanctum, It is easy, can be used both internally and externally (including the token in the request internally) Might as well rearrange the code to be easier to use internally using a helper, which would then be used in the controller and in components (No need to use a request internally then)
Stitch
StitchOP8mo ago
Makes sense, glad to hear you say that and are on the same page as I've been debating rearranging everything for the last hour to intergrate sanctum aha
Want results from more Discord servers?
Add your server