Use multiple parameters for route middleware in Laravel 6.0 - laravel

In my Laravel 6.0 app, I need to use a route with two parameters.
Route::get('view/{MyFirstModel}/{MySecondModel}', 'Mycontroller#view')
->middleware(['can:view,MyFirstModel,MySecondModel']);
I tried also with:
Route::get('view/{MyFirstModel}/{MySecondModel}', 'Mycontroller#view')
->middleware(['can:view,MyFirstModel|MySecondModel']);
In my Policy I have:
public function view(User $user, MyFirstModel $first, MySecondModel $second) {
var_dump("I enter");
}
However, it doesn't work, and the policy is never called. How can I pass two parameters in my route middleware?

I found my error.
Seems that I should use this sintax:
Route::get('view/{MyFirstModel}/{MySecondModel}', 'Mycontroller#view')->middleware('can:view,MyFirstModel,MySecondModel')
Without parentheses.

Related

Unidentified Controller when using a route that calling a controller

Good day, and thank you for reading this problem
I have a problem where I'm using a different parameter but it doesn't work, here's the problem code
Route::get('/profiles','ProfilesController#index');
But when I'm using this code it worked perfectly fine
Route::get('/profiles',[ProfilesController::class, 'index']);
Here's the controller
class ProfilesController extends Controller
{
public function index()
{
return profiles::all();
}
}
You need to use full namespace App\Http\Controllers\ProfilesController#index
use App\Http\Controllers\ProfilesController;
// Using PHP callable syntax...
Route::get('/profiles', [ProfilesController::class, 'index']);
// Using string syntax...
Route::get('/profiles', 'App\Http\Controllers\ProfilesController#index');
If you would like to continue using the original auto-prefixed controller routing, you can simply set the value of the $namespace property within your RouteServiceProvider and update the route registrations within the boot method to use the $namespace property.
More info:
https://laravel.com/docs/8.x/upgrade#automatic-controller-namespace-prefixing

Custom Routes not working - 404 not found

I'm trying to create a custom route. The must be in this format: http://localhost:8000/home-back-to-school but instead I get a 404 not found error. http://localhost:8000/posts/home-back-to-school works, but that's not what I'm trying to get working.
My routes on web.php are defined as: Route::resource('posts',PostsController::class);
I modified the Route Service Provider by adding the code below:
parent::boot();
Route::bind('post',function($slug){
return Post::published()->where('slug',$slug)->first();
});
The published scope is defined in the Post Model file(Post.php) as:
public function scopePublished()
{
return $this->where('published_at','<=',today())->orderBy('published_at', 'desc');
}
I've done previously with laravel 5.x, now struggling with laravel 8.x
Link to the Documentation: Laravel 8 Documentation
You should define a custom route since you don't want to use the resourceful route for this method.
In your web.php
// Keep all your resource routes except the 'show' route since you want to customize it
Route::resource('posts', PostsController::class)->except(['show']);
// Define a custom route for the show controller method
Route::get('{slug}', PostsController::class)->name('posts.show');
In your PostController:
public function show(Post $post)
{
return view('posts.show', compact('post'));
}
In your Post model:
// Tell Laravel your model key isn't the default ID anymore since you want to use the slug
public function getRouteKeyName()
{
return 'slug';
}
You may have to fix your other Post routes to make them work with this change since you are now using $post->slug instead of $post->id as the model key.
Read more about customizing the model key:
https://laravel.com/docs/8.x/routing#customizing-the-default-key-name
You should also remove the code you have in the boot method and use the controller instead.
Finally, make sure your post slug is always unique for obvious reason.
Note:
You may run into problems if your other routes are not related to the Post model.
Imagine if you have a route called example.com/contact-us. Laravel has no way to "guess" if this route should be sent to the PostController or the ContactController. contact-us could be a Post slug or it could be a static route to your contact page. That's why it's generally a good idea to start your urls with the model name. In your case, it would be a good idea for your Post route to start with "/posts/" like this: http://example.com/posts/your-post-slug. Otherwise you may run into all sorts unexpected routing issues.
Don't fight the framework: Always follow best practices and naming conventions when you can.

routing with model and variable

I am trying to test a custom email verification code with route model binding, when 2 wildcards are used, laravel always returns a 404.
this is my route in api.php
Route::get('/verify_contact_email/{id}/{hashed_key}', 'CustomEmailVerifyController#verifyContactEmail');
this is the controller with verifyContactEmail
public function verifyContactEmail(UserContactEmailVerify $id, $hashed_key) { return $id; }
when I remove the wildcard {hashed_key} and the $hashed_key, the model shows. I read up on laravel routing documentation, there is no mention of multiple wildcards or passing variable thru URL. Am I doing it wrong? Any help is much appreciated.
You should try this
public function verifyContactEmail($id, $hashed_key) {
$id = UserContactEmailVerify::findOrFail($id);
if(isset($id)){
return $id;
}
}
There is no problem with the route model binding or controller functions. The problem was discovered that routes do not work with hashing or bcrypt, str_random(20) has replaced the verification code instead of bcrypt.

Use Policies with apiResource Routes

Currently I'm writing a Laravel 5.6 REST api. Now I want to secure my endpoints:
Each user in my application has a role. Based on that the user should be able to access some endpoints and otherwise should get a 403 error. For this I would like to use Policies because, when used as middleware, they can authorize actions before the incoming request even reaches my route or controller.
I declare my endpoints like this:
Route::apiResource('me', 'UserController');
My problem now is that if I want to use Policies as middleware I have to specify the (HTTP) method like this middleware('can:update,post'). How should I do this when I use apiResource in my route declaration?
BTW: Currently I have written a FormRequest for each method (which is a pain) and do the authorization there. Can I simply return true in the authorize method after switching to Policies middleware?
Since you are using FormRequest::class to validate the request data, it is best practice to first check is the user is authorized to make the request. For Laravel 5.6 the cleanest solution would be to specify each policy manually in the __construct() method of your resource controller.
public function __construct()
{
$this->middleware('can:viewAny,App\Post')->only('index');
$this->middleware('can:create,App\Post')->only('store');
$this->middleware('can:view,post')->only('show');
$this->middleware('can:update,post')->only('update');
$this->middleware('can:delete,post')->only('delete');
}
If your were validating form data inside your controller instead of using FormRequest::class, a cleaner solution would be to also authorize the user inside the controller.
public function store(Request $request)
{
$this->authorize('create', Post::class);
// The user is authorized to make this request...
$request->validate([
//Validation Rules
});
// The form data has been successfully validated...
// Controller logic...
}
Since Laravel 5.7 you can do all of this using one line of code on your controller's __construct() method.
public function __construct()
{
$this->authorizeResource(Post::class, 'post');
}
You can define route groups, routes that have a common behaviour (middleware, prefix etc. ).
The following should work:
Route::middleware('can:update,post')->group(function () {
Route::apiResource('me', 'UserController');
//more routes
});
You can prefix routes as well:
Route::middleware('can:update,post')->group(function () {
Route::prefix('users')->group(function () {
Route::apiResource('me', 'UserController'); //Translated to ex: /users/me
Route::prefix('books')->group(function () {
Route::apiResource('{book}', 'UserController'); //Translated to ex: /users/me/book_1
});
});
});
P.S: I haven't used resources before but it should do the job

middleware does not working laravel 5

I'm trying to use auth middleware within my controller at construct method with except argument and it does not working.
I created my controller with artisan command and its contains methods like create, edit, show, etc.
here is my construct:
public function __construct()
{
$this->middleware('auth', ['except' => ['index', 'show']]);
}
if i visit some methods like edit and create when i'm not logged in middleware does not works and i can see the content. i also tried only instead of except, same result.
did you change Authenticate.php for auth middleware this function
public function handle($request, Closure $next)
{
}
I figure out that problem was with my addressing/
i had except index and show at my construct and i was trying to access the edit method with /controller/edit which is wrong, because controller assume the edit part as an index method argument, so i changed the url to /controller/1/edit and it's working.
it was my bad, cause i used Codeigniter for a long time, sometimes i still think that i'm working with Ci.

Resources