Code Monkey home page Code Monkey logo

laraask's Introduction

laraAsk

What is the difference between Middleware vs Guards vs Gates/Policies in Laravel

I wondered about this as well, and after some reading, here's what I've concluded:

Middleware Typically runs on a route (but you can also run it on controller methods) and can be used to filter or inspect incoming requests.

One example would be auth, which determines if the person trying to request a particular route is authenticated (logged in) to the system. Another example would be to check that a request has a specific header (e.g. if you want to check that the app is sending a X-MYAPP-CUSTOMHEADER header or something)

As mentioned, middleware can be defined on a route (e.g. in web.php or api.php) or in a controller.

An example in web.php:

// Get all the posts, but only if the user has signed in to the website

Route::get('/posts', [PostController::class, 'index'])->middleware('auth');

An example in PostController.php:

public function __construct() {
    // Apply the `auth` middleware to every function in this controller
    $this->middleware('auth');
    // Apply the `signed` middleware, but only to the functions `download` and `delete`
    $this->middleware('signed', ['only' => ['download', 'delete']]);
}

Gates Gates are functions defined in your AuthServiceProvider.php file (in the App\Providers folder) and specify what a user is allowed to do and what they're not allowed to do. For example:

Gate::define('delete-post', function (User $user, Post $post) {
    return $user->id === $post->user_id;
});

Then in your PostController's delete method:

public function delete(Request $request, Post $post)
{
    if (Gate::denies('delete-post', $post)) { // Returns true if `$post->user_id` is not the same as `$user->id` (a.k.a the user is not allowed to delete this post)
        abort(403);
    }

    $post->delete();
}

You can also use some helper methods in your blade templates:

@can('delete-post', $post)
    <!-- Show a link to the delete page here -->
@endcan

(I've expanded on this below)

Guards Guards are a way to specify how users are authenticated for requests.

In a project I'm working on, I have a jwt (JSON Web Token) guard on my API routes. This means that when I do something like auth()->attempt(['username' => 'test', 'password' => 'test']);, the auth() function will try and authenticate me using the jwt guard.

Which guard to use is specified in auth.php. Mine currently looks like this:

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],

    'api' => [
        'driver' => 'jwt',
        'provider' => 'users'
    ],
],

So in this case, requests coming in via the browser will have a session assigned when they log in, and requests coming in via an API call will need to get / provide a token to authenticate. Both will look up the users table to check the username / password when authenticating.

You can specify which guard to use with the auth() call:

auth('api')->attempt(['api_key' => 'abc1234'])

(and side note, I got caught up with this, as I was wondering why auth()->user() wasn't returning the current user, and that's because web was the default guard, and I was trying to get the user who had authenticated via api, so be sure to be explicit about which guard!)

Policies Policies work similarly to gates, but just apply to a specific model and are stored in their own file (in App\Policies)

You can create one by using php artisan make:policy PostPolicy -m Post. It'll create a file called PostPolicy.php which will create a bunch of functions:

viewAny // Can the user even look at this model? If no, they'll be denied for all the below methods
view // Can the user look at the specified Post?
create // Can they create a new Post
update // Can they edit / update the specified Post?
delete // Can they (soft) delete the specified Post?
restore // Can they restore the specified (soft) deleted Post?
forceDelete // Can they force delete the specified Post?
Typical function(s) would look like this:
public function viewAny(User $user)
{
    // If this returns true, then the other methods will be evaluated.
    return $user->can_view_posts;
}
public function forceDelete(User $user, Post $post)
{
    // If this returns true, then the user can force delete the post.
    // This depends on viewAny being true
    return $post->user_id == $user->id;
}

One thing to note, is that viewAny is NOT the same as "view all"! Think of viewAny as the front door to a building. If viewAny is true, you can go into the lobby, but you can't look inside any of the rooms unless view for a particular room is also true.

I believe you can also use the @can in blade templates with policies:

@can('forceDelete', $post)
    <!-- Show button to force delete a post here -->
@endcan

And the inverse too:

@cannot('view', $post)
    <!-- Show a greyed out button or something -->
@cannot

As well as the @canany for checking multiple permissions:

@canany(['edit', 'delete'])
    <!-- Show something if the user can edit OR delete -->
@endcanany

Conclusion I hope this has been useful. I certainly learned a lot while reading up on this. There's way more to this than I thought, so it's worth checking out the Laravel documentation because I may be right in some things, but I may be waaay off in other things.

laraask's People

Contributors

amrkhaleds avatar

Watchers

 avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.