تماشای این درس نیاز به اشتراک حرفه‌ای دارد.

Extract Blade Component0:00

Now that you understand the basic approach here, let's clean things up. Back in our Vue, all of this stuff here, this is your title, your body, that's your standard form elements. But this right here, this is exclusively Honeypot code. So as our first step, let's remove it and extract it to a component. We'll call it Honeypot. All right, in our components directory, honeypot.blade.php, I'll paste it in. Temporarily, I'm going to turn it back on just so we can see it, but yeah, if I come back to Firefox, reload, and yeah, we still get the same thing. So now we have a Blade component that can be applied to any form.

Move Logic to Middleware0:35

back to Firefox, reload, and yeah, we still get the same thing. So now we have a Blade component that can be applied to any form. Now I'll warn you later, we really don't need the labels and the styling. So ultimately, these will be two simple inputs. But just for now, to make it not such an eyesore, I'll keep it like this, and then we'll remove it at the end. Okay, that helps with the Vue. Now if I come back to my routes file, we still have all of this, and I don't want to do that for every single form that I submit. So why don't we instead extract this to a piece of middleware?

for every single form that I submit. So why don't we instead extract this to a piece of middleware? php artisan, make me a middleware. Now we can apply this middleware either by giving it a key, like you see here, or, little tip, you can also just reference the class path there, and Laravel will take care of it for you. Okay, let's click on through, and we'll start by pasting all of this in here, and then we'll get cleaning. Okay, so we already accept the $request. So why don't we just change this up, like so.

Okay, so we already accept the request. So why don't we just change this up, like so. And then in this case, let's grab that, and change it to request->input. Next, let's just get rid of this. Let's clean it up a little bit, and here we go. So now we have a route-specific middleware that we can turn on and off when we need to. It'll begin by checking, all right, let's look for this unique string here. This is our honeypot field name, and if that doesn't exist as part of the form request, something's going on here, because we expect that to be there. So let's go ahead and abort, it's probably spam.

of protection. One, if they take longer than three seconds and they fill this out, it's going to fail. And two, if they leave this blank, but they fill it out super quick, it will also fail. Okay, so notice at this point, we're just trying to make things reusable. We took that logic in the controller and we moved it into a middleware. Next, in our view, we took the HTML specific tags and we moved those into a Blade component. So now notice, by the way, if we did not include this at all, but we did add that middleware, it's going to fail. It'll think something fishy is going on here, let's abort, it's probably spam. So if you include that middleware, you have to also include the directive or the Blade

Add Config Options4:24

Now we already decided things like the fieldName and the fieldTimeName, maybe those should be configurable, and then maybe the timeout, the length, should also be configurable. Maybe for your projects, if it's filled out quicker than five seconds, it should fail, or maybe one second, that needs to be configurable. So we could do this in a couple ways. All of these could be passed in as parameters, and then in your routes file, you could just send it through here, or we're going to reach into a config file instead. So let's start with this one here, my name. Okay, let's come on back, and we'll just call it honeypotField, fieldName, maybe, and paste that in.

Okay, let's come on back, and we'll just call it honeypotField, fieldName, maybe, and paste that in. Next, we have another one. What would this be? I need to think about some of these. fieldTimeName, maybe, and paste that in. And then what's the final one? How long to wait? I need to think about this one. time is way too generic.

I need to think about this one. Time is way too generic. This isn't our timeout, though. It's not your limit. It's sort of the opposite. This represents the minimum amount of time it can take. Again, these are my two second names, minimum time. Good enough for now. If you have some better ideas, let me know in the comments, but that'll get us started. So now, if we were to come back, we could just look for config honeypot .field name.

Okay, a little lengthy, but it's now fully configurable. So why don't we do this? Why don't we call this config, like so. And then in all of these cases, select that one, that one, that one, I can replace it with our array, and then close it out. All right, next, this is too long. Why don't we grab this section here and extract it to a method? How about timeToSubmitForm? And I'll paste that in. And then I could use the request helper or just accept it here.

And I'll paste that in. And then I could use the request helper or just accept it here. Pass it through. Next, config, I'm going to bring that back to config/honeypot. Okay, so now we have a method that will return to us the time it took to submit the form. And if that is less than the minimum time we expect, then we abort. Just about done. Okay, final step, at least for our quick first pass, I want to remove the duplication here. So why don't we add a method here called abort. And I'm going to take this one here, like so, return that, this abort, add it here,

So why don't we add a method here called abort. And I'm going to take this one here, like so, return that, this abort, add it here, and here. So now we have this new configuration file, where we can specify, I'm sorry, you saw this honeypot.php, not blade. Okay, but anyways, we can override what these fields are, but we're still not referencing them within our component. As you see here, it's still being hardcoded. So you have a couple options here. The quick and dirty option would be just add a little php tag up here, fieldName, and

So you have a couple options here. The quick and dirty option would be just add a little php tag up here, fieldName, and then you would just go right into the config. So honeypot.fieldName, and then another fieldTimeName, like so. And then let's find all of these and replace it with fieldName. And then another one here, fieldTimeName. And that's it. So that's kind of the quick and dirty way to do it. But I think it would work. Let's come back, have a look here.

But I think it would work. Let's come back, have a look here. Notice the ID is my name. But if you decide you want to change this, let's go back to our config, honeypot, actually, that should be too many mistakes, Jeffrey, we'll call that honeypot. If we changed it to new name, something like that, if I now come back to Firefox and give it a refresh, you'll see it is referencing, oh, it's not. You know what, I'm probably, honeypot.blade.php, honey, yeah, I'm sorry, honeypot, that'll do it. And there we go.

Create Component Class10:18

So there's a little more I want to do, but if you think about it, we are in pretty good shape at this point. We have a configuration file for the basics. Next we have a new middleware that can be added to any route. Just reference it like so. Finally, we have a honeypot Blade component like so. And actually while we're here, why don't we go ahead and if you don't like this, some people don't mind, other people would shun that. So if you don't want to go with this approach, we can instead graduate this to a full component class.

So if you don't want to go with this approach, we can instead graduate this to a full component class. So if I were to say php artisan, make me a Blade component called honeypot. The view already exists because we manually created it, but you'll now see a view components honeypot file. So what we could do is pass it through here. And let's see, what were the ones we needed? The fieldName and the fieldTimeName. fieldTimeName. And again, all of these are going to come from the config.

Field time name. And again, all of these are going to come from the config. Honeypots.fieldname. Honeypot.fieldtimename. All right, so now we're grabbing those values from our component class like so. It loads the view and we no longer need to add it here. Come back to Firefox. Give it a refresh. Ooh, undefined variable field name. Hmm, that's surprising.

Ooh, undefined variable fieldName. Hmm, that's surprising. Maybe do we need to clear the view cache? Yeah, okay, that did it. Yeah, sometimes be careful when you're dealing with these Blade components or directives or custom directives. Sometimes you need to clear that view cache for it to take effect. But yeah, now we still get the same thing here. So that's my name. Now to wrap up, we have one more episode where I'm going to show you how to think like a

So get rid of that, reformat. We don't need any classes that are presentational. And so we end up with something like that. Now again, if we come back and refresh, it looks ugly. There's no styling there at all. But don't forget, in real life, you're going to have a display set to none, and you're not going to see it at all. So if you want, this could even become an inline component. It's up to you. But we could delete it, come to our honeypot component.

It's all contained within a single class, which I think is kind of cool. Anyways, come on back, give it a refresh. It's going to, oh yeah, it's going to fail again, only because we haven't set these. You can either grab it up here, you could do it in the constructor, whatever you want. This field name is config, honeypot, exact same thing. So format this however you want. And then, if you want to get especially crazy, use var. But I think that'll work. Come back, give it a refresh, and there you go. So let's refresh, act like a spammer, fill it out, ooh, honeypot, undefined index in

Come back, give it a refresh, and there you go. So let's refresh, act like a spammer, fill it out, ooh, honeypot, undefined index in our middleware. I'm expecting something you've been seeing for a while here. Config, config honeypot, oh, we already did it. Focus Daniel-san. Okay, give it another shot, act like a spammer, and it still fails. microtime, was I too, a little too liberal there? One more time, act like a spammer, please work, and it did work. So we're good there.

Add Enable/Disable Flag14:42

One more time, act like a spammer, please work, and it did work. So we're good there. I guess if you want, we could send through the config array here, like that, and then you could just do, like we did before, config. I guess that makes it a little more consistent, but yeah, whatever you want. Last thing, bear with me, before we talk about package development, or thinking in terms of package development, is we probably do need a way to disable this. When you're writing your test, you don't want a middleware that checks how long it took to fill out the form, because you want it to be as quick as possible in that case. So we might say, if config, if honeypot is enabled, or if it's not enabled, then let's

to fill out the form, because you want it to be as quick as possible in that case. So we might say, if config, if honeypot is enabled, or if it's not enabled, then let's just continue on to the next request, skip it, we're not going to do anything here. This way, in your phpunit files, or your phpunit.xml file, you could disable it. Or you could do that automatically in the package. It's good to provide an option there. So let's just go to honeypot, at the very top, by default, it is enabled. But maybe this can read from an .env file. So we'll say honeypot enabled defaults to true. Yeah, so now, your middleware will check, if it's not enabled, then we don't need to

So we'll say honeypotEnabled defaults to true. Yeah, so now, your middleware will check, if it's not enabled, then we don't need to do anything. So continue on to the next request. So have a look. Right here, we act like a spammer, it's going to catch us. But for whatever reason, in your .env file, if you set honeypotEnabled to false, it's not going to work. So you might want to do this for staging, or you might want to do this for testing. Notice, we acted like a spammer, and we were able to bypass that protection.

دوست دارید گاهی خبرهای Laracasts را ایمیل کنیم؟