Which is better way to verify access method In Laravel - php

I've Blog website where all user can post Blog.I have learned about Gates,Policy and Middleware .Please come to know that i am using Auth() Default Authentication Process in Laravel. I want to protect user (A) blog from other users.
Now I have many things to handle this.
Using Auth if(Auth()->user->id==$blog->user_id)
Using Gate if(Gate::Allow('blog_protection',$blog))
Using Policy if(Auth::user()->cant('blog_protection',$post))
Using Middleware $this->middleware('blog_access')
Please tell if i am wrong Meaning of that functions then what is best method to handle this request for more reusable . Many Thanks In Advance.

I would consider writing a policy class for blog model resource. Multiple reasons :
You can list all access methods related to blog in one file to easy to track
You can do just $this->authorize('access_method_name', Blog::class) in controller
You can pass extra arguments to the method to filter it conditionally
If you have a method outside controller and you need to add filter(ideally the controller authorize() would filter it out) but still you can use
$user->can() or $user->cant()..
which will internally use the same policy.
Also to mention you can use this in blade directives #can()...# endcan #cannot...#endcannot
Middleware is something which would intervene in every request specified in the route group or all requests if its registered as global middleware group. If you want an access filter applicable globally in all routes then middleware is a better option. But for specific resource, I would prefer policies.
In short middleware for request filtering and handling whereas Policy for managing granular level access controls.

Related

Middleware laravel

I am new in laravel and I have one problem with middleware. On official laravel site, I found code for creating controller.
When I creating controller it is recommended to add middleware in constructor or this is only if I need some additional functionalities?
Also, if I include auth middleware, did I get some benefits by default, like security checks or similar or I must to rewrite middleware code first?
class UserController extends Controller {
/**
* Instantiate a new controller instance.
*
* #return void
*/
public function __construct() {
**//this part includes some protection or similar by default ?**
$this->middleware('auth');
}
}
Middleware is used when you want to filter the HTTP requests entering your application.
For example, including the built-in auth middleware will restrict non-authenticated users from accessing a page and redirect them to the login screen.
You can include middleware into your controller and routes.
In the controller you do it like so:
public function __construct()
{
$this->middleware('auth');
}
For a route you do this:
Route::get('/page', 'MyController#myMethod')->middleware('auth');
Do I need to include this part of code when I creating controller or not ?
As I said in my comment, it really depends on the desired functionality whether you use it or not.
An example
Your homepage should probably be accessible for anyone who visits you website, while your dashboard should only be displayed to authenticated users.
That's where you would include the auth middleware.
Question #1
Do you need to use $this->middleware('auth'); in your controller?
Answer: Only if you want to protect all of the methods of that controller from non-authenticated users and only allow signed in users to access controller actions.
Question #2
Do you get benefits for using the auth middleware?
Answer: Yes you do, only authenticated users can access the controller or routes protected by auth.
** Question #3**
Do you need to write your own middleware?
Answer: Only if you need to override a middleware or need extra functionality that is not already provided (php artisan make:auth), but if you are rolling your own login functionality then you will likely need/want to create your own middleware.
Resources:
Look in App\Http\Kernel.php and you will see that the $routeMiddleware array matches the auth middleware to the \Illuminate\Auth\Middleware\Authenticate::class which actually verifies that the current user is logged in and allows them to pass, if they are not logged in then it will redirect them to the '/login' route.
You will see that Laravel uses quite a bit of middleware by default, such as starting the session, encrypting cookies and protecting against CSRF forgery.
There are several ways to implement middleware, which I'm sure you saw in the docs.
Some Helpful Video Tutorials:
I suggest you watch each of the free series usually titled Laravel from Scratch on Laracasts.com. I would also suggest watching all of from Laravel 5.7 back to 5.1 or 5.0 as Jeffrey Way may use different techniques in similar situations and it will provide you with a great tips and helpful information as to how things work along with some Laravel best practices along the way. I've subscribed to him for years and work in Laravel everyday and I still learn some new things from watching his videos, a subscription is easily worth 10-20 what he charges.

Controllers separation of concerns in laravel

I have been working on a project using php with laravel for a week now, I just want to make sure I am following the best practices.
I really like the idea of Resource controllers and CRUD, they make sense and I chose to follow this approach. However, should I be using them on a model where different users have different access rights on it?
suppose I have different types of users (user, admin, agent) that have different access rights on the same models. Which of the following approaches is more appropriate for this case?
Create a normal controller for each user type along with its middleware that authorizes the access to this controller. Then add a route to that controller with that middleware.
Create a resource controller for each resource (model), create a route group for each user type containing all routes for this user type from the defined controllers along with a middleware for this route group.
In other words, where both of the following are possible, should controllers definition be based on user type or resources themselves?
Personally I name my controllers based on the resources and then handle the roles/user types via middlewares

Proper way to route vue/ajax requests in laravel?

I'm new to laravel and making a web service that can function without javascript (if a user has it disabled or something.)
But it would be a better user experience to be able to perform certain actions without refreshing the whole page. I'd like to be able to say, send a form without reloading the page, or refresh notifications.
The options I can think of are:
1) Send the ajax to the same route as the pure html form, but with an extra variable and make my laravel respond with json when that variable is detected
2) Use the API route? Will this detect the currently logged in user?
3) Make new routes for everything ajax, even though they function the same as my current routes (aside from returning a view)
Also, does the CSRF token work multiple times in a row, or do I need to disable that to handle multiple ajax form posts in a row without page refreshes?
I recommend keeping the routes separate, both to prevent weird caching bugs and for your own sanity as the code changes over time.
Laravel is set up out of the box to let you define web routes in routes/web.php and api routes in routes/api.php. Routes defined in your api.php file will be available at /api/* by default. It's much easier to manage changing the application this way, rather than trying to make your controllers do both views and api responses.
With Laravel Passport, your API routes can detect the currently logged in user via the auth:api middleware when combined with adding the Laravel\Passport\Http\Middleware\CreateFreshApiToken to your web middleware group.
https://laravel.com/docs/5.7/passport#consuming-your-api-with-javascript
An easy way to manage the duplicated controllers (one for web and one for api) is to put Api controllers in their own namespace, with php artisan make:controller Api/FooController. You can even set up your Api routes to look for controllers in this namespace by default by editing RouteServiceProvider.php.

How to manage access based role-users without method checking ways using laravel 5.2

My actual project needs to implement an ACL for the diferent roles in my users.
For now, I have like 4 roles defined by the client (Administrator, Head of Departament, Secretary and Teachers) but he wants to create more roles whenever he needs it.
Knowing this the clue is I want to know if is there any way to control the system access without checking the access in each method of my system. Laravel provides my the Authorization services but is not enough for the desing of my system, but I think is a deprecated way checking every method.
My idea is implement something before enrouting any request and check if the user has access depending on his roles, in this way I won't need to check it in every method as the actual solution that laravel Authorization services, laravel-acl of Kodeine or similars offers me.
If someone has an idea to set forth this Idea please answer this.
Also I want to know if this could affect the system security and how and how I can handle that.
Thanks in advance.
If you want to use role-base access control only, it's very easy to create own middleware where you check passed roles. Now in your routes you can protect routes depending on user roles, for example:
Route::group(['middleware' => 'authorize:admin,secretary'], function() {
// your route here
});
You have sample role middleware in Laravel documentation here.

Laravel: Difference Between Route Middleware and Policy

Developing an app with laravel I realised that what can be done with Policy can exactly be done with Middleware. Say I want to prevent a user from updating a route if he/she is not the owner of the information, I can easily check from the route and can do the same from the policy.
So my question is why should I use policy over middleware and vice versa
I'm currently going through a small refactor with my roles, permissions and routes and asked myself the same question.
At the surface level, it appears true middleware and policies perform the same general idea. Check if a user can do what they are doing.
For reference here's the laravel docs...
Middleware
"May I see this? May I go here?"
HTTP middleware provide a convenient mechanism for filtering HTTP
requests entering your application. For example, Laravel includes a
middleware that verifies the user of your application is
authenticated. If the user is not authenticated, the middleware will
redirect the user to the login screen. However, if the user is
authenticated, the middleware will allow the request to proceed
further into the application.
Of course, additional middleware can be written to perform a variety
of tasks besides authentication. A CORS middleware might be
responsible for adding the proper headers to all responses leaving
your application. A logging middleware might log all incoming requests
to your application.
https://laravel.com/docs/master/middleware#introduction
In my reading, Middleware is about operating at the request level. In the terms of "Can this user see a page?", or "Can this user do something here?"
If so, it goes to the controller method associated with that page. Interestingly enough, Middleware may say, "Yes you may go there, but I'll write down that you are going." Etc.
Once it's done. It has no more control or say in what the user is doing. Another way I think of it as the middleperson.
Policies
"Can I do this? Can I change this?"
In addition to providing authentication services out of the box,
Laravel also provides a simple way to organize authorization logic and
control access to resources. There are a variety of methods and
helpers to assist you in organizing your authorization logic, and
we'll cover each of them in this document.
https://laravel.com/docs/master/authorization#introduction
Policies however, appear to be more concerned with doing. Can the user update any entry, or only theirs?
These questions seem fit for a controller method where all the calls to action on a resource are organized. Retrieve this object, store or update the article.
As tjbb mentioned, middleware can make routes very messy and hard to manage. This is an example from my routes file:
The problem
Route::group(['middleware' =>'role:person_type,person_type2',], function () {
Route::get('download-thing/{thing}', [
'as' => 'download-thing',
'uses' => 'ThingController#download'
]);
});
This gets very hard to read in my route file!
Another approach with policies
//ThingController
public function download(Thing $thing)
{
//Policy method and controller method match, no need to name it
$this->authorize($thing);
//download logic here....
}
Route middleware allows you to apply request handling to a large range of routes, instead of repeating the code in every controller action - checking authentication and redirecting guests is a good example. Controllers instead contain logic unique to specific routes/actions - you could use middleware for this, but you'd need separate middleware for every route's logic and it would all get very messy.
Policies/abilities are simply a way of checking user permissions - you can query them from a controller, or from middleware, or anywhere else. They only return true or false, so they aren't equivalent to controllers or middleware. Most of the time abilities will be comparing a user to another model, which will have been loaded based on an identifier sent to a controller action, but there are probably some applications for use with middleware too.
I have asked myself the same question. In practice, I predominantly use middleware.
My most common usage is when authorisation is only allowed for a specific user, for instance:
public function update(User $user, user $model)
{
return $user->id === $model->id;
}
Though, even in the instance above, Yes, one could do without it and write their own logic in the controller to do the same thing.
I also like the before method, which I use to allow the administrator full-privileges for a model, for example:
public function before($user, $ability)
{
if ($user->admin === 1) {
return true;
}
}
The main reason, though, why I have started to use Policies on some Laravel projects is because of what you can do with blade. If you find yourself setting permissions numerous times for the same user authorisation in your blade files, for example, to show an edit button, then Policies may become very useful because you can do the following with them (and more):
#can('update', $post)
<button class="btn btn-primary">Edit Post</button>
#endcan
#cannot('create', App\Models\Post::class)
<div class="alert alert-warning">You are not allowed to create a post</div>
#endcannot
I sometimes find these Policy-referencing blade methods to be super useful, when wanting to group authorisation in one place.

Categories