Why group middleware does not work for apiResources? - laravel

Here is a API routing with sanctum:
Route::group(["middleware" => "auth:sanctum"], function () {
Route::apiResources([
'profile' => ProfileController::class,
'specialization' => SpecializationController::class,
'specialization/filter' => SpecializationController::class,
'location' => LocationController::class,
]);
});
When I ask any controller it returns a response despite the user is not authorized.
Why Route::group(["middleware" => "auth:sanctum"], function () {} does not work?

I believe the value for the middleware key should be an array:
Route::group(["middleware" => ["auth:sanctum"]], function () {
Route::apiResources([
'profile' => ProfileController::class,
'specialization' => SpecializationController::class,
'specialization/filter' => SpecializationController::class,
'location' => LocationController::class,
]);
});

Related

Why does an inertia route change?

In a Laravel/Inertia application, I try to store vinylRecords.
Therefore I created a vinylRecords resource.
Route::resource('vinylRecords', VinylRecordController::class)->only(['index', 'create','store', 'edit', 'update']);
In the frontend, the store function looks like:
methods: {
submitForm() {
this.$inertia.post(route("vinylRecords.store"), this.form, {
onSuccess: (response) => {
alert(Object.keys(response.props))
this.form.reset();
},
});
}
},
Sometimes, the routing is right and the Laravel stores the new record. But most of time, Laravel redirects to the index method without storing the data.
The store method:
public function store(StoreVinylRecordRequest $request)
{
$data = $request->validated();
$record = VinylRecord::create($data);
$record->labels()->sync($data['label_ids']);
$record->styles()->sync($data['style_ids']);
$record->specials()->sync($data['special_ids']);
return Inertia::render('vinylRecord/index', [
'records' => VinylRecordResource::collection(VinylRecord::all()),
'vinylRecordId' => $record->id
]);
}
To solve the problem, I created a new controller with a new route to store the data:
Route::post('storeVinylRecord', [StoreVinylRecordController::class, 'store'])->name('storeVinylRecord');
But the problem was the same.
How is it possible, that the routing changes from one request to the other? Is there an big error in the code from my side?
Edited: Add the StoreVinylRecordRequest
public function rules()
{
return [
'artist' => 'required|string',
'title' => 'required|string',
'barcode' => 'nullable|integer',
'genre_id' => 'nullable|integer',
'country' => 'nullable',
'year' => 'nullable|integer',
'label_ids' => 'nullable',
'style_ids' => 'nullable',
'special_ids' => 'nullable',
'thumb' => 'nullable|string',
'cover_image' => 'nullable|string',
'quantity' => 'nullable|integer',
'speed' => 'nullable|integer',
'part_type' => 'nullable|string',
'storage_location' => 'nullable|string',
'supplier_id' => 'nullable|in:suppliers,id',
'purchasing_price' => 'nullable|numeric',
'selling_price' => 'nullable|numeric',
];
}

Which is valid syntax for route of ads/ad_locations editor?

In my Laravel 8 app I want to make route of ads/ad_locations editor
Route::group(['middleware' => ['auth'], 'prefix' => 'admin', 'as' => 'admin.'], function () {
...
Route::group(['prefix' => 'ads'], function ($router) {
...
Route::resource(
'/{ad_id}/ad_locations',
AdLocationController::class
)->name('admin.ads.ad_locations');
But I got error clearing routes :
$ php artisan route:cache
ArgumentCountError
Too few arguments to function Illuminate\Routing\PendingResourceRegistration::name(), 1 passed in /mnt/_work_sdb8/wwwroot/lar/AdsBackend8/routes/web.php on line 112 and exactly 2 expected
at vendor/laravel/framework/src/Illuminate/Routing/PendingResourceRegistration.php:110
106▕ * #param string $method
107▕ * #param string $name
108▕ * #return \Illuminate\Routing\PendingResourceRegistration
109▕ */
➜ 110▕ public function name($method, $name)
111▕ {
112▕ $this->options['names'][$method] = $name;
113▕
114▕ return $this;
1 routes/web.php:112
Illuminate\Routing\PendingResourceRegistration::name()
+3 vendor frames
5 routes/web.php:119
Illuminate\Support\Facades\Facade::__callStatic()
Which syntax is valid and how to ref in in blade file ?
MODIFIED BLOCK:
I modified in routes/web.php :
Route::group(['middleware' => ['auth'], 'prefix' => 'admin', 'as' => 'admin.'], function () {
Route::group(['prefix' => 'ads'], function ($router) {
Route::resource('/{ad_id}/ad_locations', AdLocationController::class, [
'names' => [
'index' => 'admin.ads.ad_locations.index',
'store' => 'admin.ads.ad_locations.store',
'edit' => 'admin.ads.ad_locations.edit',
]
]);
and run command with success :
php artisan route:cache
But in blade file using it :
<a class="btn btn-primary" href="{{ route('admin.ads.ad_locations.edit',[$ad_id, $nextAdLocation['id']]) }}">
{!! showAppIcon('edit') !!} Edit
</a>
I got error :
(Symfony\\Component\\Routing\\Exception\\RouteNotFoundException(code: 0): Route [admin.ads.ad_locations.edit] not defined. at /mnt/_work_sdb8/wwwroot/lar/AdsBackend8/vendor/laravel/framework/src/Illuminate/Routing/UrlGenerator.php:429)
[stacktrace]
Which way is correct ?
Thanks!
Function name() doesn't work with route::resource, because it's a collection of routes, it should be used with individual routes like:
Route::get('user/create', [UserController::class, 'create'])->name('user.create');
You can either supply a "names" array as the third parameter (options) parameter to the resource route, like:
Route::resource('user', UserController::class, [
'names' => [
'index' => 'admin.ads.ad_locations.index',
'store' => 'admin.ads.ad_locations.store',
// etc...
]
]);
or, you can use with as keyword, like the one you have used in your route:
Route::group(['middleware' => ['auth'], 'prefix' => 'admin', 'as' => 'admin.ads.ad_locations.'], function () {
Route::group(['prefix' => 'ads'], function ($router) {
Route::resource('/{ad_id}/ad_locations', AdLocationController::class);
});
});
In the above snippet, I have used your complete route "admin.ads.ad_locations" name in "as" attribute's value. But, this last one will be treated as prefix for every single route like this:
admin.ads.ad_locations.{ad_id}.store
admin.ads.ad_locations.{ad_id}.create
...
You can also, use function names() like below:
Route::resource('/{ad_id}/ad_locations', PhotoController::class)->names([
'create' => 'admin.ads.ad_locations.build'
'show' => 'admin.ads.ad_locations.view'
]);
Answer For Rectified Section of the Question:
Because you are using "as" attribute in your route as well, the route names generated for you will be:
admin.admin.ads.ad_locations.store
admin.admin.ads.ad_locations.create
admin.admin.ads.ad_locations.create
You can either remove the as attribute from your route, like:
Route::group(['middleware' => ['auth'], 'prefix' => 'admin'], function () {
Route::group(['prefix' => 'ads'], function ($router) {
Route::resource('/{ad_id}/ad_locations', AdLocationController::class, [
'names' => [
'index' => 'admin.ads.ad_locations.index',
'store' => 'admin.ads.ad_locations.store',
'edit' => 'admin.ads.ad_locations.edit',
]
]);
});
});
or, you can avoid using "admin." in your routes names, like:
Route::group(['middleware' => ['auth'], 'prefix' => 'admin', 'as' => 'admin.'], function () {
Route::group(['prefix' => 'ads'], function ($router) {
Route::resource('/{ad_id}/ad_locations', AdLocationController::class, [
'names' => [
'index' => 'ads.ad_locations.index',
'store' => 'ads.ad_locations.store',
'edit' => 'ads.ad_locations.edit',
]
]);
});
});

How fix redirecting with parameter have error

In my Laravel 5.8 app when there are no data in session I need to redirect to some default control.
I do
return redirect()->route('admin.oauthAdminCallback/' . $form_action);
When in routes/web.php defined :
Route::group(['middleware' => ['auth', 'isVerified', 'CheckUserStatus'], 'prefix' => 'admin', 'as' => 'admin.'], function () {
Route::get('oauthAdminCallback/{form_action}', [ 'uses' => 'Admin\EventsController#oauthAdminCallback']);//->name('oauthAdminCallback');
But I got error :
Route [admin.oauthAdminCallback/calendarActionUpdate] not defined.
If in first line $form_action has value : “calendarActionUpdate”.
Which is correct way ?
MODIFIED :
I tried this way
return redirect()->route('admin.oauthAdminCallback',$form_action);
and this way
return redirect()->route('admin.oauthAdminCallback')->with([
'form_action' => $form_action,
]);
But in both cases I do not have amy error but method was not called!
In my routes/web.php :
Route::group(['middleware' => ['auth', 'isVerified', 'CheckUserStatus'], 'prefix' => 'admin', 'as' => 'admin.'], function () {
Route::get('oauthAdminCallback', [ 'as' => 'oauthAdminCallback', 'uses' =>'Admin\EventsController#oauthAdminCallback']);
// The method below is not called!
public function oauthAdminCallback()
{
session_start();
die("-1 XXZ oauthAdminCallback");
return redirect( is ignored and I can not understand why?
So you're calling the route by its name so
try this
return redirect()->route('admin.oauthAdminCallback',$form_action);
Mention your route as
Route::group(['middleware' => ['auth'], 'prefix' => 'admin', 'as' => 'admin.'], function () {
Route::get('oauthAdminCallback', [ 'as' => 'oauthAdminCallback', 'uses' => 'Admin\EventsController#oauthAdminCallback']);
});
And your callback as below
return redirect()->route('admin.oauthAdminCallback', $form_action);
Tried and tested.

how to set specific scopes for specific client in laravel passport

Route::get('/', function () {
$query = http_build_query([
'client_id' => 3, // Replace with Client ID
'redirect_uri' => 'http://127.0.0.1:8001/callback',
'response_type' => 'code',
'scope' => 'admin user'
]);
return redirect('http://127.0.0.1:8000/oauth/authorize?'.$query);
});
I'm new to using Laravel Passport,I want to set dynamically client scope, not declare in scope by hard coded.
Not specific to passport, more Laravel, but you could try this
Route::get('/{scope}', function ($scope) {
$query = http_build_query([
'client_id' => 3, // Replace with Client ID
'redirect_uri' => 'http://127.0.0.1:8001/callback',
'response_type' => 'code',
'scope' => $scope
]);
return redirect('http://127.0.0.1:8000/oauth/authorize?'.$query);
});
Info here

Middleware except

I have a group of route that I apply auth Middleware.
How should I except the tournaments.show ????
I only found examples with $this->middleware syntax, but none with Route::group
Route::group(['middleware' => ['auth']],
function () {
Route::resource('tournaments', 'TournamentController', [
'names' => [
'index' => 'tournaments.index',
'show' => 'tournaments.show',
'create' => 'tournaments.create',
'edit' => 'tournaments.edit', 'store' => 'tournaments.store', 'update' => 'tournaments.update' ],
]);
});
You can except the show route from the resource() as:
Route::group(['middleware' => ['auth']],
function () {
Route::resource('tournaments', 'TournamentController',
[
'names' =>
['index' => 'tournaments.index',
'create' => 'tournaments.create',
'edit' => 'tournaments.edit',
'store' => 'tournaments.store',
'update' => 'tournaments.update'
],
'except' => ['show'],
]
);
});
And then define it outside the group as:
Route::get('tournaments/{id}', 'TournamentController#show')->name('tournaments.show');

Resources