Rendering Users List0:00
Now, if you've never built a single-page application before, there's one very big security concern that you need to be aware of. So let's have a look at that in this episode. I will switch to the Users tab, and why don't we turn this into a list of users that we fetch from the database and then send to the client. All right, so let's go into Users, and yeah, I think we can get rid of this old section here where we show the current time, and instead we're going to accept a list of users. Users is an array. Okay, so as you can imagine, we'll have some kind of unordered list, and then I'm going to simply iterate over our users.
Okay, so as you can imagine, we'll have some kind of unordered list, and then I'm going to simply iterate over our users. So for user and users. Next it's a good practice in Vue to always set a key on your loops, so that'll be the user's ID, and then finally I will set the body of this list item to the user's name and reformat. Okay, so now at this point, of course, we're still not going to see anything because we're not yet passing users from our controller. That's the next step. But to set this up, I do need a database.
Creating SQLite Database1:04
That's the next step. But to set this up, I do need a database. So why don't we quickly whip up maybe an SQLite database. Something like that. And then within my database directory, I will add our database, database.sqlite, which is the default. Okay, finally, and this is all basic Laravel, if I run my migrations, included in those will be a users table that has a name, an email address, a password, a few other things. So let's do that now. Switch to the terminal, run php artisan migrate.
Seeding User Records1:34
So let's do that now. Switch to the terminal, run php artisan migrate. There we go. And if I quickly open this, here we go. And sure enough, I do have a users table, but it's currently empty. Okay, let's quickly seed it. So if I switch over to my seeders folder, you'll see this is what Laravel includes out of the box. And it has a little snippet here to quickly whip up 10 users. Why don't we change that number to 100?
And it has a little snippet here to quickly whip up 10 users. Why don't we change that number to 100? Now I can run php artisan db:seed. And if we did everything correctly, we should now have 100 users in our database table. And we do. Okay, so that setup is out of the way. The next step, let's go to our routes file again. And let's see, right here is where we access the users. So no longer will I be passing through the current time. Instead, I will send through a list of users.
Sending Users to Client2:24
So no longer will I be passing through the current time. Instead, I will send through a list of users. So let's say user. And at least for now, we're going to say user all. But there's a bit of a red flag here. And you'll see why shortly. Okay. But yeah, if I come back and refresh, I think I'm going to see 100 users. And I do. Great.
And I do. Great. It's working. But yeah, that red flag. Let's come and look at view dev tools. And let's see what exactly is being passed from the controller. Here's our users. It's an array of 100 items. But yeah, notice that every item is an object that includes a lot of data. Now again, in this case, it's a brand new project.
Exposing Sensitive Fields3:00
But yeah, notice that every item is an object that includes a lot of data. Now again, in this case, it's a brand new project. So this is fairly minimal. But you can imagine for any real life project, your users table probably includes a dozen different columns, maybe related to their subscription status, or maybe unique billing tokens that you don't want to expose to them. But the problem is right now, all of that information is being passed to the client, which if you think about it presents two problems. The first problem is you're passing through more data than the page actually requires. And that means more data is going over the wire.
The first problem is you're passing through more data than the page actually requires. And that means more data is going over the wire. But the second issue, and the really big issue, I think, is that again, the entire structure of your users table is being passed to the client, including any fields that you don't want the user to see. Now I imagine this is pretty clear, but just to make it crystal clear, yeah, maybe your users table includes some kind of token, maybe for Stripe or something like that. I'll just say Stripe token. And that can be nullable. OK.
And that can be nullable. Okay. Then real quick in my UserFactory, think of this as the blueprint for a dummy User record. And we'll say right here, actually, I can just duplicate this, create a dummy Stripe token. Okay. So now I'm going to refresh my database from scratch, and I'm also going to seed it in the process. Okay.
the process. Okay. So again, if we reopen that file, we should have a new Stripe token column. So now think about it. Any and every time you add a new column to your users table, well, because we used that users all method, all of the data is being passed to the client. And we can access it again right here, props, users, and notice there's the Stripe token being exposed to the user. And it's not just their token, it's the Stripe token for every single user, including the email address for every single user.
Returning Only Needed Data4:59
And it's not just their token, it's the Stripe token for every single User, including the email address for every single User. So if I wanted to, I could access this page and plug the email address for every User in your system. So yeah, clearly not a great idea. Okay. Instead, it's better to be explicit. So if I go back to my routes file, instead of blindly passing User all to the client, let's first map over it so that we can return a subset. So for example, maybe we want, well, actually at the moment, the only thing we're making
let's first map over it so that we can return a subset. So for example, maybe we want, well, actually at the moment, the only thing we're making use of is the user's name. So why don't we keep it as basic as we can possibly get? And then later, if we need more fields, we can pass it through at that point. Okay. So have a look. Give it a refresh. And now if we take a look, and this time we'll go to the actual Users page component, yes, we still have our users array, but notice that each user object contains only the data
And now if we take a look, and this time we'll go to the actual users page component, yes, we still have our users array, but notice that each user object contains only the data that we actually need and none of the data that we don't want them to see. So this is a really important pattern that you need to follow in your own projects. When you're building a traditional server side application, there's not a big deal with passing something like user all to a view. And that's because that data isn't being exposed to the end user. But when you're building a client side application, yeah, the rules are a little bit different. It will be exposed through an Ajax call. And again, you can always review those if you want to see the actual call taking place.
It will be exposed through an Ajax call. And again, you can always review those if you want to see the actual call taking place. Switch to your network tab, turn on XHR, visit a page, and sure enough, we make a request to the users endpoint, and that returns the JSON for all of our users. But luckily, because we were thoughtful, we're not exposing anything that we don't want the user to see.
