WEBVTT

00:01.040 --> 00:07.820
Okay guys, so it's time to create and run some middleware so we can see how it all works.

00:08.360 --> 00:15.140
So let me jump to directory structure and we're going to create Middlewares inside app folder.

00:15.440 --> 00:22.070
Let me create a folder called Middlewares to use our convention of plural names.

00:22.100 --> 00:27.050
And the first one can be called view or just view middleware.

00:27.050 --> 00:29.780
It's up to us how we call those classes.

00:30.200 --> 00:33.260
So let me call this just view.

00:33.470 --> 00:35.270
This is our first middleware.

00:35.300 --> 00:38.210
Now let me quickly explain what this is going to do.

00:38.240 --> 00:40.340
First I'm going to add the namespace.

00:40.340 --> 00:43.820
This is app Middlewares.

00:44.300 --> 00:52.430
So we've got our front controller which shares the currently authenticated user as a global view variable.

00:52.430 --> 01:00.490
And from the lack of a better place, we just have put that into the front controller I think this is

01:00.490 --> 01:04.990
the best use case, or that's an ideal use case.

01:04.990 --> 01:12.550
To put it differently, for a middleware that's global, that always has to run because we're going

01:12.580 --> 01:14.200
to need this always.

01:15.340 --> 01:19.360
So that's the first thing I'd like to move to a middleware.

01:19.360 --> 01:25.000
And that's why I've created a view middleware which will just do exactly that.

01:25.030 --> 01:28.210
Class name will be view same as the file name.

01:28.210 --> 01:33.100
And it needs to implement our middleware interface.

01:33.100 --> 01:39.490
To which I'm gonna jump next because we need to implement this handle method.

01:39.520 --> 01:48.070
It's super important to remember that the whole logic of middleware depends on the next target to be

01:48.070 --> 01:55.690
called, which we need to call inside this middleware so that this chain doesn't get broken unless we

01:55.690 --> 01:56.650
want it to.

01:56.680 --> 01:59.160
Like in this example.

01:59.310 --> 02:07.740
So in here I'm gonna just copy the code or move the code from this front controller.

02:07.740 --> 02:10.770
So this is view share Authuser.

02:11.160 --> 02:13.170
So we need to import the auth class.

02:13.170 --> 02:20.040
And I can't easily import the view class from core namespace because we have the name conflict in here.

02:21.000 --> 02:27.390
So to import it I would need to use an alias which can be a core view.

02:27.420 --> 02:31.230
This is what you do if you have the naming conflict.

02:31.230 --> 02:37.830
And the first thing is the middleware needs to do something needs to be useful.

02:37.830 --> 02:40.200
And this is what this middleware is doing.

02:40.200 --> 02:48.900
But then we always need to remember to return the call to next middleware or the final route.

02:49.560 --> 02:54.120
So this looks fine and we need to register this middleware.

02:54.150 --> 02:57.740
I think we can do it inside this routes file.

02:57.770 --> 02:59.450
Let's jump to it.

02:59.810 --> 03:03.200
So in this file we've got the route definitions.

03:03.200 --> 03:06.560
Let me now add the global middleware here as well.

03:06.560 --> 03:13.280
So to the router we are calling Add global middleware which needs the class name to run.

03:13.280 --> 03:18.800
We can use our view class name by importing the class.

03:18.800 --> 03:22.490
And we are using the class constant.

03:22.580 --> 03:26.390
Now this is registered and I think it should run.

03:26.900 --> 03:31.310
So let me jump to our page and see if that's the case.

03:31.310 --> 03:33.170
So we've got some issue.

03:33.500 --> 03:36.590
We are calling an HTML.

03:36.860 --> 03:42.770
That is strange, but I think there must be some issue inside the router implementation.

03:44.270 --> 03:48.590
So we call the middleware and that's our implementation.

03:48.590 --> 03:50.180
Let me take a look.

03:50.180 --> 03:56.740
So we first store the final target which is the controller action.

03:56.740 --> 04:05.890
Then we should go through every middleware and create a chain by creating a middleware, passing the

04:05.890 --> 04:07.720
next thing to call to it.

04:07.720 --> 04:14.710
And finally we start the chain by calling the last middleware that was registered.

04:14.710 --> 04:16.300
So I see the problem here.

04:16.300 --> 04:21.670
We are actually, or I am actually running those middlewares immediately.

04:21.670 --> 04:24.970
Instead this should be a function.

04:24.970 --> 04:29.950
It can be an arrow function because that is a one liner.

04:29.950 --> 04:33.370
So I shouldn't be calling those middlewares immediately.

04:33.370 --> 04:42.790
Instead, I should be creating those classes and wrapping everything in functions so that I can create

04:42.790 --> 04:47.440
a chain of function calls like we see right here.

04:47.440 --> 04:56.760
And I trigger this chain by starting the last element that was added, and then it works backwards so

04:56.760 --> 05:00.870
that it calls the middleware middleware and finally the action.

05:01.020 --> 05:03.150
This might be complicated.

05:03.180 --> 05:09.720
There is a lot of abstraction here, but in reality this is quite simple.

05:09.750 --> 05:13.410
Now I think it should work right now.

05:13.410 --> 05:15.360
Let me refresh the page.

05:15.360 --> 05:17.370
And indeed it works.

05:17.370 --> 05:25.050
And we still get access to the user from the view, which means that the middleware has worked fine.

05:27.360 --> 05:33.720
So to understand it better, I think we should be doing some logging.

05:33.720 --> 05:42.150
So here, instead of using the arrow function, let me just add a full function and I'm gonna do error

05:42.180 --> 05:42.750
logging.

05:42.750 --> 05:45.960
That would let us see something in the terminal.

05:48.180 --> 05:48.510
Okay.

05:48.510 --> 05:57.530
So this needs to have this use statement now to use the middleware and to use whatever needs to be called

05:57.530 --> 05:58.490
next.

05:59.570 --> 06:07.970
Let me fix this keyword to be a function and before it runs whatever it needs to run, let's just do

06:07.970 --> 06:16.760
a simple error log that will say we are okay, or maybe something different.

06:16.790 --> 06:17.960
Middleware.

06:18.980 --> 06:22.370
Running middleware.

06:26.120 --> 06:34.520
Okay, so now we will be always seeing in the log in which order the middleware was run.

06:36.710 --> 06:38.510
Let me add a semicolon in here.

06:38.510 --> 06:43.580
And if I refresh this page we should already see something.

06:44.720 --> 06:46.880
Okay so we've got that middleware.

06:46.880 --> 06:50.600
We are running this middleware right here.

06:51.710 --> 06:54.440
Now let's create some more middleware, shall we?

06:54.470 --> 06:59.180
So we've got one global middleware that should be always run.

06:59.180 --> 07:08.480
But we've got cases where middleware is not global like the authentication we don't always require.

07:08.660 --> 07:10.490
Um what's this error here.

07:10.520 --> 07:16.460
Um return value must be of type string null returned.

07:17.030 --> 07:18.410
Um, okay.

07:18.440 --> 07:19.820
I somehow returned.

07:19.850 --> 07:21.530
Removed this return keyword.

07:21.560 --> 07:21.950
Okay.

07:21.950 --> 07:24.020
Let me go back to our topic.

07:24.050 --> 07:28.880
So another middleware that we can create is authentication.

07:28.880 --> 07:31.370
Let's jump to the command controller.

07:33.290 --> 07:43.280
So instead of checking if the user is authenticated and then redirecting him, we can just make sure

07:43.280 --> 07:49.090
that in this action it won't run if the user is not authenticated.

07:49.090 --> 07:52.240
So for that we can create another middleware.

07:52.390 --> 07:55.600
Let's call that the auth middleware.

07:59.500 --> 08:01.390
So let's add a namespace here.

08:01.390 --> 08:06.280
This is app Middlewares and the class is called auth.

08:06.310 --> 08:10.840
It implements the middleware.

08:11.380 --> 08:17.590
And let me quickly jump to this one and copy paste this method.

08:22.750 --> 08:27.400
And now let me just move the logic from this controller.

08:28.600 --> 08:34.300
So in this middleware I just want to check if the auth.

08:34.330 --> 08:34.660
Okay.

08:34.690 --> 08:37.360
So we need to import the auth class again.

08:37.360 --> 08:40.180
This time we need to use an alias.

08:41.860 --> 08:43.330
So this is our alias.

08:43.330 --> 08:49.050
So if the user is well, Falsy is not authenticated.

08:49.080 --> 08:50.010
Is null.

08:50.040 --> 08:54.780
Then we do router unauthorized which would essentially break the chain.

08:54.780 --> 08:58.650
It would redirect to 401 page.

08:59.130 --> 09:05.940
Otherwise we just move to the next middleware and this needs to be registered.

09:05.940 --> 09:09.660
But first this is a root middleware.

09:09.660 --> 09:16.830
That's why in the router object I call add root middleware I call it off.

09:16.860 --> 09:23.010
And only then I use the actual middleware class.

09:24.030 --> 09:31.470
So this is first registering the possibility of adding this middleware to a route.

09:31.560 --> 09:36.840
It's not registering the middleware to be run and for it to be run.

09:36.840 --> 09:39.780
I added in this route definition.

09:39.780 --> 09:44.960
So there is this fourth argument which accepts an array of middleware names where.

09:44.990 --> 09:53.210
Now I can use this shortcut which is auth, which should now protect this route from running if someone

09:53.210 --> 09:55.190
is not authenticated.

10:00.110 --> 10:10.220
So in here I should be able to safely remove this code and instead when creating the command I would

10:10.220 --> 10:11.570
just do auth.

10:13.730 --> 10:14.480
User.

10:14.480 --> 10:19.700
And at this point I am certain that the user object is there.

10:19.700 --> 10:27.740
I can safely call it because I know that I have verified previously using middleware that this action

10:27.740 --> 10:35.090
would never be called if the user is not authenticated, and we'd like to do the same with CSRF later

10:35.090 --> 10:37.580
on, but this one would be global.

10:37.580 --> 10:46.270
We want it always and you can see how simple this action can become if we just remove the code that

10:46.270 --> 10:47.800
is often repeated.

10:48.010 --> 10:53.800
We don't have the CSRF middleware yet, that's why I'm just going to leave it there.

10:54.010 --> 10:57.760
But now let's see if this will work.

10:57.760 --> 11:05.650
Let me jump to a post and see if middleware won't crash.

11:05.980 --> 11:07.630
So I'm adding the comment.

11:07.660 --> 11:15.820
It went fine to actually verify that I should make sure not this form.

11:15.820 --> 11:17.230
It should be okay.

11:17.260 --> 11:21.100
So that's the post form we just called show.

11:21.280 --> 11:32.410
And the way I'm going to test that is I just want this form to be displayed at all times, even if I

11:32.440 --> 11:33.340
sign out.

11:33.340 --> 11:46.470
So I have signed out now and I go to This page, and I'd like the form to be always visible.

11:46.500 --> 11:51.510
Let me remove this code like this.

11:51.510 --> 12:00.090
And okay, now I see the form and when I submit something, I should just be directed to 401 page.

12:00.090 --> 12:02.760
And this should happen in the middleware.

12:03.930 --> 12:05.550
Let me add a comment.

12:05.850 --> 12:12.720
Everything has worked fine and here we can see that the view middleware was run first, then the auth

12:12.720 --> 12:19.320
middleware was run specifically for that route, which confirms that the middleware has redirected us

12:19.320 --> 12:22.290
to 401, which is unauthorized.

12:22.320 --> 12:28.140
So now let me bring back this code for displaying the form conditionally.

12:28.710 --> 12:37.230
But anyway, I think you can see how this middleware works and how it has simplified the way we can

12:37.230 --> 12:38.760
write those controllers.
