I am really struggling with Laravel auth. I read the manual many times, went to the code, but I still don't understand how the level of intrication of the Auth module.
As far as I understood, the app files that take part of the Auth are:
Manager: Auth (Illuminate\Auth\AuthManager)
Service Provider: AuthServiceProvider (Illuinate\Foundation\Support\ProvidersAuthServiceProvider)
Middleware: Authenticate
Gate
Model: User
Controller: LoginController
It seems these controllers LoginController, RegisterController, ... are called by magic, hardcoded deep down in Illuminate\Routing\Router. But, I do not want to use or register any ResetPasswordController, neither ForgotPasswordController simply because I do not hold any passwords on my application.
So in my case I do no store any email or password in my database. My authentication is done with OAuth2, the only think I do, is collecting an access token that I store on my database.
The question is:
How can I use the builtin Laravel Auth system that I am forced to use anyway because some providers require an access to app('auth')?
What then is the best solution in my case?
Rewrite the whole Auth Manager and override the Router to remove the burred links to the unneeded controllers
Tweak the existing Auth system to fulfill my needs
I am quite lost...
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.
I am using Laravel 5.3 and am having some issues with the authentication.
Prior to me working on this program the developer set it up so all of the controllers that need to authenticated are extended from an account controller class (which extends the base controller etc). The account controller class just runs $this->middleware('auth') which should run the handle method in the authenticate class to check if there is an active session and if not redirect the user to the login page.
The strange thing is that this works for some controllers but not for others even though the controllers are all extended from the same account controller. In the controllers it is not working, it does not seem to even get to the handle method in the authenticate class.
I was wondering if there is something in laravel that specifies what routes to authenticate and i need to define in there or does anyone have any other idea of why this seems to work for some pages and not others even though the controllers are setup the same?
You can put a check at Route level like:
Route::group(['middleware' => 'auth'], function () {
// All the routes enclosed in this block are protected
});
// Put unprotected routes outside the block
i'm new to laravel, just started building my first laravel application (v.5.2). I come from codeigniter. In CI i used to create a pre-controller hook to check login status and set language before any controller loads. Application-wide stuff.
I can't find anything on pre-controller hooks in the laravel docs. There is something called "middleware" however that might do the job. At what point does this Middleware kick in?
Am i on the right track? or is there a better way do these jobs in laravel.
Yes you can do that with middleware.
Middleware will execute before hitting your controller's method.
Though I would suggest you to make a base controller where you can create a method to do this stuff and call that method from the constructor of the base class.
Edit
So I just read that you want to check if the user is logged in. For this purpose you have auth middleware.
Yes, middleware is the best option. I'm using Auth Middleware to implement this kind of feature in my application.
Like below.
public function __construct()
{
$this->middleware('auth' , ['except' => ['show']]);
parent::__construct($this);
}
Here I want to give permission to only show action without login.
You can also use form request to check permission/authentication for each action.
For Laravel 5 # (5.2)
You can have a look on App\Http\Controllers\Controller
Actually all other controllers extends this base controller.
Issue :
1. If routes are not use controller in this case it not works.
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.