5.3 Implementing the Portfolio Routes on the Server
Our UI is useless without the server working to serve data. So we'll focus on completing the necessary server routes in this lesson. We'll also write some custom middleware for authenticating client requests.
1.Introduction2 lessons, 12:18
2.Getting Started2 lessons, 20:32
3.Users and Authentication5 lessons, 54:30
4.Managing Currencies5 lessons, 46:15
5.Managing Our Portfolio5 lessons, 50:13
6.Security1 lesson, 10:49
7.Conclusion1 lesson, 00:38
5.3 Implementing the Portfolio Routes on the Server
In the previous lesson, we worked on the UI for adding addresses to our portfolio. But of course it doesn't work because there's nothing on the server to handle those requests. So that is what we are going to focus on in this lesson. And let's just go to the routes folder, and let's create a new file called portfolio. So just like with our currencies, we are creating another file that we are going to use that contain the routes just for our portfolio. Now, I'm going to open up the currency routes because we need all of the first three lines as well as our first route here. Because if you'll remember, in our UI, we need to retrieve the currencies for our select box. So the only difference here is that the URL is going to be portfolio/currencies. However, we are going to do the same exact thing that we did with currencies, and we are going to import our portfolio routes into the api page or file. So let's go ahead and do that as well. And let's see, we'll call that portfolio, we are going to import portfolio and then we will set up that route. So that the prefix is already going to be there, and so everything inside is going to be relative. So with that out of the way, let's go back. So our currencies is simply just going to use our Currency model. We're going to find all of the currencies and return them. Now, we do need our user model, so let's go ahead and import that. And then we will focus on creating a new record. Now, we're going to have to start incorporating the authorization token here because that is how we determine what user is currently logged in. But before we get there, let me go ahead and say module.exports, the router, so that I don´t forget to do that later. Okay, so we wanna route for a post request for the route of our portfolio. And we want to be able to create a record based upon the data that's coming in. But in order to do that, we need to know the user. So we're going to have to incorporate some authentication on our part. So inside of routes, we're going to create another file, we're going to call it auth.js. And there are a few things that we need, if we go to the login file, we have everything. We need the user, we need jwt, and config, so let's grab those three things and let's paste them in here. And we are going to eventually have two functions because what we're going to do is have two pieces of middleware, one for authenticating admin, one for authenticating just users. So we're going to import our authentication in here. And then we are going to apply that middleware to our currencies and our portfolio routes, but we'll get there in a moment. For right now, though, what we want to do is have a function, and I'm gonna call it isAuthenticated because this is for determining if the user is authenticated. So we will have our request, our response, and our next. And then we just need to go through the process of checking to see if the user is authenticated. So the first thing we need is to retrieve our token. So we are going to use the get method on our request, and we will get the Authorization token. Now, if there's not a token, then there's nothing to authenticate, or rather nothing to authorize. So what we will do is return the status of 403, and we will also include a message that says, No token. No token, no joken, so you can't get past us. But If you do have a token, then we have to verify that token, and that's where we will use jwt. We have a method called verify, where we pass in the token, we pass in the secret value from our config, and then we have a callback. Now, if we got an error, then of course, the user's not authenticated. So if we check for an error, we are going to return a status of 403, and let's also include a message. But in this case, we'll say Invalid token, because if we have an error, it's an invalid token. Otherwise, then we want to try to find the user based upon the ID that was used to create the token. Because if you'll remember, let's look at login, we signed an object that has an ID property, we set it to the user._id, and it's done using that secret value. So at this point, our decoded object is available to us. And so now we want to try to find a user by the given ID from that object that we created, so we will say decoded.id. Hopefully we find a user. But if not, well, we have to take that into account as well. So we will have to check to see if we have an error. And if we do, let's just do this, we'll just say Invalid token, why not? And if we don't have a user, we'll say the same thing. Because if we have an object that has an ID, but that user doesn't exist, well, then the token is invalid, so that's an invalid token as well. So if we make it past these two checks, then we have a valid user and we can do a couple of different things. Since our portfolio is going to depend upon this middleware, what we could do then is create our own property on the request object, and we could just set it to user. That way we already have the user, we don't have to hit the database again. And voilà, we have the user. But, [LAUGH] but don't forget to call next, definitely need to call next. Okay, so, We need to export this. So module.exports, and for right now, we'll just have the isAuthenticated. We'll come back, and we'll have a check for if the user is an admin, which is almost the same thing, it's just one other check involved. So let's go to our api file, and let's pull in that auth as well. So we'll just auth, we will require auth, and then we will use that middleware here, so we'll say auth.isAuthenticated, and then we'll have our portfolio route. So let's look at the command line, and we have an issue here. Okay, so that is auth, line 8. Okay, we need closing parenthesis there, and still. Since we messed all of that up, is that something that I copied and pasted multiple times? No, okay, good. All right, so our code is compiling, yay! Okay, so now let's go back to portfolio. Now that we have a user available to us, all we really need to do then is add something to the portfolio. Because we have that user.portfolio, so let's say user equals, and we will say req and portfolioUser. We have the portfolio property. And since this is an array, we're going to push in an object where we set the address equal to the address from the request body. And then we set the currency to the currency from the request body. Now, this currency is an actual currency object from our database. Because, if you'll remember, the UI is retrieving the currencies, we are displaying those currencies in a select box. The V-model for that select box is one of these currency objects. So we don't to do anything here other than save the user, and then we can send something back, which, let's just do an empty object. So once again, let's check our console, everything's working okay there. So let's give this a whirl, and the only thing that can go wrong is that it doesn't work. Of course something doesn't work right out of the box, and the server responded with a status 404 not found, api portfolio. Well, the 404 is to be expected, but the api. Well, let's go and look at our portfolio vue, or not the portfolio, but the AddressCreator, and we do use api here. So we need to import that from, and I think we go back one, and there we go. So that should fix that, let's do a hard refresh. And we will still get the 404 because that particular URL doesn't exist yet, so we click on Add Address that came up. That looks horrible, though, we're gonna have to look at that. But as far as the address is concerned, we just go to the Phore block explorer, we can go to the Api, and down here at the bottom is the donation address, so we will use that for our example. And let's paste that in, we save, and let's check the database. So let's refresh what we have, and let's see, admin, nothing got saved. So let's look at the server, and we see that the embedded failed for value, that's the ID at path currency. We were supposed to have the currency object, so I messed something up. Let's look at our options, the value, [LAUGH] that's not supposed to be the ID, that's supposed to be the currency. Okay, so with that, and with a non-zero exit code, is that gonna be a problem? That might be a problem, so let's just run that again. All right, so with that hopefully fixed, let's do another hard refresh here. And we will add address, we will choose Phore, we will paste in what is supposed to be that. And we will save the address. So then we will go back to our database, we will examine our admin user. And we saved that object, that's great. So in the next lesson, what we need to do is display our portfolio. We need to also retrieve the balance so that we can display that. And then also make deleting these records possible, I don't think we want to edit them. In hindsight, there's really not much to edit. We can't really edit something after the fact, we can't change the currency for an address, otherwise it won't work. So we will just add the delete functionality, and then we will be done as far as our portfolio UI.