در حال بارگذاری ...

مرور استخراج یک کلاس احراز هویت0:00

All right, welcome back, as always. So yeah, in the last episode, we took our first refactoring step by extracting a dedicated class that is responsible for validating the login form. And already, I think this has improved readability a good bit. So why don't we keep pulling on that thread a little bit and continue on to the next part of the page. And yeah, once again, I'm going to say out loud in an empty office what this code does. And then I will try to identify the nouns and the verbs. All right, so this code finds the User and then attempts to log the User in.

Creating Authenticator Class0:29

And then I will try to identify the nouns and the verbs. All right, so this code finds the User and then attempts to log the User in. Otherwise, return to the login form and provide a little bit of feedback. Yes, so find the User and attempt to authenticate them. That's really what's going on here. Okay, authenticate. I had a verb attempt. Maybe we can make this work. Let's go into my core directory. And why don't we add a class called, well, authenticate is a verb.

Let's go into my core directory. And why don't we add a class called, well, Authenticate is a verb. So why don't we make it a noun by saying something like AuthenticateTour? All right, next, my verb was attempt. And what parameters should I pass to attempt, if any? I don't know yet. Let's come back and take this one step at a time. So if I were to comment, well, let's just, yeah, let's comment all of it out for now. And we're going to have this new Authenticator class. All right, I will call that off.

And we're going to have this new Authenticator class. All right, I will call that off. And I know I'm going to call an attempt method. But what am I attempting to do? I'm attempting to authenticate. And to do that, I need credentials, like an email address and a password. So yeah, maybe once again, we pass through the email and the password. All right, so let's accept it here. All right, and what does attempting actually mean? Well, it means basically what we had here.

As you'll find, a lot of programming is really playing around, toying around, seeing what works, seeing what doesn't. And sometimes that means you will write code for an hour and then undo all of it in favor of something else. And that's totally fine. It's just part of the flow. Okay, so we track down the User. And then what do we do? Well, right here, we say, well, if you could find a User, then check if the password matches and call this login function.

Moving Login/Logout Methods2:36

Well, right here, we say, well, if you could find a User, then check if the password matches and call this login function. But now this feels a little weird. I have this Authenticator class that's responsible for authentication, but it's deferring to a little helper function we created an episode or two ago. That doesn't feel right. Why don't we grab login and logout and bring them into this new class like so? Okay, we'll make them both public like so. Okay, so now up here, we will defer to our login method. And then if everything's good, we redirect.

Okay, so now up here, we will defer to our login method. And then if everything's good, we redirect. Okay, again, just little baby steps, one little change at a time. And we will continue tweaking this as the episode continues. All right, so finally, what about this code, though? Well, you could move it in there. But let's talk about this. Now, what I would say is our Authenticator is doing too many things at this point. Now, I've introduced a new responsibility and a new piece of knowledge. The Authenticator knows how to load a view.

Returning Boolean From Attempt4:07

It's not the responsibility of the Authenticator class to do something like that. So in that case, I don't want that. I'm going to keep it here. But now, of course, I need to figure out, well, under what condition would it make sense to return this view? And that condition is if we were unable to log the User in. So why don't we say if you could not successfully log in the User or authenticate, on that condition, and let's reformat, on that condition alone, do we return this view? Okay, so that means attempt should return a Boolean.

It knows what to do in the event that authentication passed. And that's not quite right. The controller should be responsible for that, I think. So in that situation, we return true. Okay, so now my attempt method returns a Boolean that indicates whether or not we could successfully log the user in. So if I come up, well, why don't we do this? Let's say if we could attempt to log the user in, do something. Otherwise, do something else. Okay, and the if is a simple redirect.

Otherwise, do something else. Okay, and the if is a simple redirect. And that's what we end up with here. Okay, but I still see a lot more we can do. First up, you'll notice throughout the last 10 episodes or so, every time I want to redirect, I have to write these two, frankly, annoying lines of code. header, location, and then I write the path, and then I exit for security purposes. What does that mean though?

Adding Redirect Helper5:49

and then I exit for security purposes. What does that mean though? Let's just do it again. Empty office, what does this code do? It redirects to the homepage. Okay, the verb is redirect. I need something called redirect to help with readability. So let's just say redirect to the homepage, and then make that code work. Let's just add a simple helper function

and then make that code work. Let's just add a simple helper function in our global functions file. Redirect to a path, like so. And then I can paste in what we had before. And then let's do this. Let's replace the quotes, and then I can substitute the provided path. And yeah, that will do the exact same thing. Cool.

There's sometimes no real rhyme or reason to it. It's just what felt right at the time. And the same is true for programming, as it turns out. All right. Let's read some code. 75% of programming is reading. So let's keep reading it over and over until it makes good sense. But actually, real quick, before we do that, you'll notice that this $db variable is not being used anywhere. And that's because, of course, we extracted that logic to the Authenticator.

you'll notice that this db variable is not being used anywhere. And that's because, of course, we extracted that logic to the Authenticator. So now I can get rid of that. And then we also have two more imports that are no longer necessary. And I like what I'm seeing here. Okay, let's read the file. So we create a login form, and we try to validate the email and the password. And if that failed, then we have to return to the login form and display the errors. Otherwise, if validation passed,

And if that failed, then we have to return to the login form and display the errors. Otherwise, if validation passed, then we will attempt to authenticate the User based upon the provided credentials. And if we were successful, they're now signed in, and we can redirect them wherever they need to go. Otherwise, once again, we go back to the login form. But this time, I hardcode the errors. Okay, so I see my next refactor that I'd like to make. Notice that this and this are very similar, but they're still slightly different.

Refactoring Duplicate Error Handling8:43

Notice that this and this are very similar, but they're still slightly different. So have a look. This one returns to the login page and passes the errors from the login form. This one also returns to the login page. But this time, we hardcode an email validation message based upon that failed authentication attempt. Okay, so yeah, this can sometimes be a little tricky. So I will teach you a pretty cool refactoring strategy that I use all of the time. So whenever you're in a situation where you have two pieces of code

So I will teach you a pretty cool refactoring strategy that I use all of the time. So whenever you're in a situation where you have two pieces of code that are mostly the same, but slightly different, instead, see if you can make whatever changes necessary to make those two pieces of code identical. I'll show you an example. So if I want these two pieces to be identical, this code up here needs to be the same code at the bottom. Okay, well, how do I make that work, though? Well, it sounds like this message here that we were hardcoding

Okay, well, how do I make that work, though? Well, it sounds like this message here that we were hardcoding would instead need to come from this errors method on the FormRequest class. So it sounds like I need a way to append a new validation error to the login form. Okay, well, maybe, and let's just write it out. What would I want to do? Maybe something like addError? Or if I can, maybe I'll just do error. We give the corresponding field and then the message that goes along with it. Yeah, and if we could make that work, that would solve the problem, wouldn't it?

We give the corresponding field and then the message that goes along with it. Yeah, and if we could make that work, that would solve the problem, wouldn't it? Then this snippet here and this snippet would be identical. And once they're identical, the whole reason for this is once they're identical, we can merge them. Okay, but one step at a time. Let's go into LoginForm and add a new method called error. This will accept the field and the corresponding message. Okay, so let's just update the errors list. We pass through the field and the message.

Okay, so let's just update the errors list. We pass through the field and the message. Okay, and I think that's it. So if I come back, that solves our problem. All right, step two, merge them into one. So how do we do that? Well, I can get rid of all of this code here. And yeah, maybe at the top, we can swap out this form validation. Why don't we say if the form validated successfully, in that case, we don't return to the login page,

Why don't we say if the form validated successfully, in that case, we don't return to the login page, but instead continue on to the next step of the process, which is attempting to log the User in. Okay, but if we could not successfully log them in, that is the point where we add a new, where we manually append to the form errors list. So think about it. If we make that small adjustment, we've now refactored our way out of the duplication,

If we make that small adjustment, we've now refactored our way out of the duplication, which is really cool. Okay, so let's see. Let's read it again. Create a login form. Try to validate the credentials. If we were successful, attempt to authenticate the User. If we were successful, redirect. Otherwise, update our errors list and then return to the login page.

If we were successful, redirect. Otherwise, update our errors list and then return to the login page. Perfect. Okay, what else can we do here? Are there any other small, tiny refactors we can make? One thing I see is I only referenced this auth variable once. So again, this is a style choice, but if you like, you can automatically inline it or manually inline it if you want. Again, it's just a style choice.

And then this is what we get. And then once again, do I use the form in more than one place? Yes, I do. So I can't inline that. I need to keep it. All right, let's read it a fifth time. We load this page. We instantiate a LoginForm. We validate the form. And then we attempt to authenticate the User.

We validate the form. And then we attempt to authenticate the User. And then if that was unsuccessful, we return to the login page. I think this is looking pretty good, actually. And in fact, I think it's looking good enough that we can move on to the next episode.

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