- Read Tutorial
- Watch Guide Video
WEBVTT
1
00:00:00.620 --> 00:00:04.490
Now that we have our context and our provider built out,
2
00:00:04.490 --> 00:00:08.030
now it's time for us to actually make them functional.
3
00:00:08.030 --> 00:00:11.410
So in this guide, what we're gonna do is we're gonna make
4
00:00:11.410 --> 00:00:15.260
an API call out directly from our provider
5
00:00:15.260 --> 00:00:18.130
whenever it loads up, which in our case is
6
00:00:18.130 --> 00:00:20.960
whenever anyone accesses the application.
7
00:00:20.960 --> 00:00:22.790
And we are gonna check to see
8
00:00:22.790 --> 00:00:24.690
if the user is logged in or not.
9
00:00:24.690 --> 00:00:28.410
And we're gonna use two ways of checking this.
10
00:00:28.410 --> 00:00:31.760
The very first way is to first see,
11
00:00:31.760 --> 00:00:35.270
if there is a token stored in local storage.
12
00:00:35.270 --> 00:00:36.780
That's the very first thing we're gonna do.
13
00:00:36.780 --> 00:00:40.410
We're gonna perform a get item function check
14
00:00:40.410 --> 00:00:43.950
with local storage, we're gonna see if there is a token
15
00:00:43.950 --> 00:00:45.760
with our name on it.
16
00:00:45.760 --> 00:00:50.680
If there is then we're gonna test to see if it's valid.
17
00:00:50.680 --> 00:00:53.010
We can't simply say okay, yes,
18
00:00:53.010 --> 00:00:55.240
we have a token in local storage,
19
00:00:55.240 --> 00:00:58.850
that means that there is an admin and they're logged in.
20
00:00:58.850 --> 00:01:00.970
Because then what a hacker would be able to do is,
21
00:01:00.970 --> 00:01:03.750
a hacker could recognize that type of behavior,
22
00:01:03.750 --> 00:01:06.410
and they could just manually go in
23
00:01:06.410 --> 00:01:09.360
and create a token on local storage.
24
00:01:09.360 --> 00:01:11.920
Say that that is the, in this case,
25
00:01:11.920 --> 00:01:14.270
the devCamp space secure token,
26
00:01:14.270 --> 00:01:16.270
and they could put some gibberish in there,
27
00:01:16.270 --> 00:01:19.670
and then it would pass the test of authentication.
28
00:01:19.670 --> 00:01:20.950
That's not a good thing.
29
00:01:20.950 --> 00:01:22.280
So instead, what we're gonna do
30
00:01:22.280 --> 00:01:24.600
is we're first gonna see if the tokens there,
31
00:01:24.600 --> 00:01:27.210
but we're not gonna simply leave it at that,
32
00:01:27.210 --> 00:01:29.330
from there if it is there,
33
00:01:29.330 --> 00:01:32.027
we're gonna pass that token up to the API.
34
00:01:32.027 --> 00:01:35.620
And we're gonna see if that user is authenticated.
35
00:01:35.620 --> 00:01:38.660
So in other words, if that token is valid or not,
36
00:01:38.660 --> 00:01:41.040
so we're gonna perform those two checks.
37
00:01:41.040 --> 00:01:43.330
So that's what we're gonna do in this guide.
38
00:01:43.330 --> 00:01:45.950
So first and foremost, what we're gonna have to do,
39
00:01:45.950 --> 00:01:49.640
is we're going to have to import a few other items
40
00:01:49.640 --> 00:01:51.320
in the admin provider.
41
00:01:51.320 --> 00:01:52.940
So the first thing we're gonna do,
42
00:01:52.940 --> 00:01:57.900
is I'm gonna say useEffect because
43
00:01:57.900 --> 00:01:59.520
if you remember back when we did
44
00:01:59.520 --> 00:02:02.440
our portfolio items list component,
45
00:02:02.440 --> 00:02:06.190
we were able to use the use effect hook,
46
00:02:06.190 --> 00:02:08.600
and that is the hook that you use
47
00:02:08.600 --> 00:02:12.460
whenever you want some type of process to be triggered
48
00:02:12.460 --> 00:02:14.470
whenever the component is called.
49
00:02:14.470 --> 00:02:17.290
And so that's what we're gonna want in this case.
50
00:02:17.290 --> 00:02:19.920
Now, we also want to import axios,
51
00:02:19.920 --> 00:02:23.210
that is our library for making API calls.
52
00:02:23.210 --> 00:02:27.990
So I'm gonna say import axios from axios.
53
00:02:27.990 --> 00:02:32.650
And then lastly, we need the API URL.
54
00:02:32.650 --> 00:02:36.160
So here at the top, I'm just gonna create a constant
55
00:02:36.160 --> 00:02:41.160
variable called API URL, and then I'm gonna type that out.
56
00:02:41.360 --> 00:02:46.360
In this case, it's gonna be https://API.devCamp.space/
57
00:02:50.140 --> 00:02:55.140
and then is token underscore logged underscore in,
58
00:02:55.870 --> 00:02:59.750
and in the show notes, you can get access to this
59
00:02:59.750 --> 00:03:02.720
if you wanna just copy and paste that URL.
60
00:03:02.720 --> 00:03:04.560
In a real life scenario,
61
00:03:04.560 --> 00:03:07.670
so let's say you're building this for a company
62
00:03:07.670 --> 00:03:09.930
you're working for, you're gonna have documentation
63
00:03:09.930 --> 00:03:13.000
that's gonna provide these type of URLs to you.
64
00:03:13.000 --> 00:03:17.180
Okay, so now that we have that, now let's create a function
65
00:03:17.180 --> 00:03:20.610
that's gonna check to see if the users logged in or not.
66
00:03:20.610 --> 00:03:23.763
So I'm gonna create a function here called checklogin.
67
00:03:25.570 --> 00:03:29.650
And it's gonna take in an argument of a token.
68
00:03:29.650 --> 00:03:33.200
And so this token is gonna be the token
69
00:03:33.200 --> 00:03:35.730
we're gonna check to see if it exists,
70
00:03:35.730 --> 00:03:38.350
and then we're gonna pass it up to the API.
71
00:03:38.350 --> 00:03:41.020
The reason why I'm using this as an argument,
72
00:03:41.020 --> 00:03:44.780
is because I don't ever want the checklogin function
73
00:03:44.780 --> 00:03:48.270
to be called if the token doesn't exist
74
00:03:48.270 --> 00:03:50.000
on the user's system.
75
00:03:50.000 --> 00:03:52.500
So this is a way to protect against that.
76
00:03:52.500 --> 00:03:56.430
So we we have no need of calling checklogin,
77
00:03:56.430 --> 00:03:59.310
if there is not a token in local storage,
78
00:03:59.310 --> 00:04:00.590
because if there's an token,
79
00:04:00.590 --> 00:04:04.030
that means we're guaranteed that the user is not logged in.
80
00:04:04.030 --> 00:04:08.790
So now that we have that, I can call axios.get,
81
00:04:08.790 --> 00:04:11.710
and then we're gonna perform a few tasks here.
82
00:04:11.710 --> 00:04:15.030
First, we're gonna pass in the API URL,
83
00:04:15.030 --> 00:04:17.900
and then we need to pass in some data.
84
00:04:17.900 --> 00:04:21.460
Now this data is gonna be our token.
85
00:04:21.460 --> 00:04:24.800
So up until this point, so if you were to go to say,
86
00:04:24.800 --> 00:04:28.280
the admin login component here,
87
00:04:28.280 --> 00:04:32.170
we passed params in from our form,
88
00:04:32.170 --> 00:04:36.983
and that is the data that we sent up to create
89
00:04:38.250 --> 00:04:41.750
really to create that token, and to get that back.
90
00:04:41.750 --> 00:04:45.450
We're gonna perform a little bit of a different task here,
91
00:04:45.450 --> 00:04:49.770
we're not gonna send data up in the params instead,
92
00:04:49.770 --> 00:04:52.760
what we're gonna do is we are gonna dive into
93
00:04:52.760 --> 00:04:56.210
working with HTTP headers.
94
00:04:56.210 --> 00:05:00.140
So headers are like a metadata that we send up
95
00:05:00.140 --> 00:05:02.610
whenever we're making an API call.
96
00:05:02.610 --> 00:05:05.980
Many times you don't actually have to send in any headers,
97
00:05:05.980 --> 00:05:08.530
just like we didn't send any in
98
00:05:08.530 --> 00:05:12.200
when we were doing our admin login component.
99
00:05:12.200 --> 00:05:14.920
But here, we need to, because that's the way
100
00:05:14.920 --> 00:05:17.150
that you send a token in.
101
00:05:17.150 --> 00:05:20.880
So I'm gonna create an object here.
102
00:05:20.880 --> 00:05:23.100
And it's gonna be called headers.
103
00:05:23.100 --> 00:05:28.100
And then inside of here, we're going pass in another object,
104
00:05:28.210 --> 00:05:32.910
and this is gonna be called authorization colon,
105
00:05:32.910 --> 00:05:34.080
so that's the key.
106
00:05:34.080 --> 00:05:37.550
And then what we need to pass in is our token.
107
00:05:37.550 --> 00:05:41.110
But it has a very special syntax that you need to pass in,
108
00:05:41.110 --> 00:05:43.890
you need to see say, Bearer,
109
00:05:43.890 --> 00:05:46.190
and note that I use backticks here
110
00:05:46.190 --> 00:05:47.950
and the reason for that is because we need
111
00:05:47.950 --> 00:05:49.930
to use some string interpolation.
112
00:05:49.930 --> 00:05:54.930
So I'm gonna say Bearer space and then we're gonna pass in
113
00:05:55.210 --> 00:05:59.000
the token just like this.
114
00:05:59.000 --> 00:06:02.120
Okay, so what are we doing here?
115
00:06:02.120 --> 00:06:04.150
Well, we're making an API call,
116
00:06:04.150 --> 00:06:07.830
we're calling this token logged in endpoint,
117
00:06:07.830 --> 00:06:10.970
and then we're passing in a set of headers.
118
00:06:10.970 --> 00:06:13.080
These headers are going to say that
119
00:06:13.080 --> 00:06:15.770
we have a level of authorization,
120
00:06:15.770 --> 00:06:19.340
and that we're sending in a bearer token.
121
00:06:19.340 --> 00:06:23.180
That is what we're passing in the headers up to the API.
122
00:06:23.180 --> 00:06:26.228
Now the API knows how to parse the this data.
123
00:06:26.228 --> 00:06:29.310
So it's actually looking for headers,
124
00:06:29.310 --> 00:06:32.710
and it's looking for this authorization bearer token,
125
00:06:32.710 --> 00:06:35.380
and it's then gonna take that token,
126
00:06:35.380 --> 00:06:37.810
and it's gonna see if it's valid or not.
127
00:06:37.810 --> 00:06:40.640
So say that you have a hacker who just typed in
128
00:06:40.640 --> 00:06:44.530
some random gibberish and save that in local storage,
129
00:06:44.530 --> 00:06:45.890
that's not gonna work.
130
00:06:45.890 --> 00:06:49.340
Because what's gonna happen is this token,
131
00:06:49.340 --> 00:06:53.890
is going to be decrypted by the API
132
00:06:53.890 --> 00:06:55.410
and it's gonna see, okay,
133
00:06:55.410 --> 00:06:58.870
is this a valid user or not?
134
00:06:58.870 --> 00:07:02.010
And then it's gonna connect this API call
135
00:07:02.010 --> 00:07:04.180
with your user account.
136
00:07:04.180 --> 00:07:06.850
And that's the way that the authorization works.
137
00:07:06.850 --> 00:07:09.220
So let's test this out to see if it's working.
138
00:07:09.220 --> 00:07:11.840
So at the very end here, I'll get rid of the semi colon.
139
00:07:11.840 --> 00:07:15.730
And I'm gonna say then response,
140
00:07:15.730 --> 00:07:19.160
and then a fat arrow function and curly brackets.
141
00:07:19.160 --> 00:07:21.810
And then I'll just console log it out first.
142
00:07:21.810 --> 00:07:26.810
So say console log res and then let's get the response data.
143
00:07:28.060 --> 00:07:30.920
If I hit Save here, this will kind of format it
144
00:07:30.920 --> 00:07:33.850
so you can see this a little bit better.
145
00:07:33.850 --> 00:07:36.900
Let me zoom out here just so you can see everything.
146
00:07:36.900 --> 00:07:40.370
And if you're following along and typing what I'm typing,
147
00:07:40.370 --> 00:07:42.710
you'll see you have a get request,
148
00:07:42.710 --> 00:07:45.530
with the first argument being the API URL,
149
00:07:45.530 --> 00:07:49.460
the second being this object that contains the headers,
150
00:07:49.460 --> 00:07:52.600
and then we're calling then because this is a Promise,
151
00:07:52.600 --> 00:07:54.450
and for right now we're simply
152
00:07:54.450 --> 00:07:56.610
printing out the response data.
153
00:07:56.610 --> 00:08:00.170
Now it's always a good idea to also catch any server errors.
154
00:08:00.170 --> 00:08:03.300
So at the very end of the lines,
155
00:08:03.300 --> 00:08:08.300
I'll say .catch, and then we're going to listen for errors,
156
00:08:08.690 --> 00:08:11.090
and then I'll just console log these out as well.
157
00:08:11.090 --> 00:08:16.090
So say console log error, and error.
158
00:08:16.670 --> 00:08:19.220
Okay, so we have this function built out,
159
00:08:19.220 --> 00:08:22.530
but nothing's actually happening with it yet.
160
00:08:22.530 --> 00:08:24.630
So we're not actually calling this function.
161
00:08:24.630 --> 00:08:26.070
So that's what we need to do,
162
00:08:26.070 --> 00:08:29.130
we need to use our use effect hook,
163
00:08:29.130 --> 00:08:31.090
and that's where we're gonna trigger
164
00:08:31.090 --> 00:08:33.010
this check login function.
165
00:08:33.010 --> 00:08:37.030
So inside of here, I'm gonna say useEffect,
166
00:08:37.030 --> 00:08:39.450
and this is exactly the same syntax
167
00:08:39.450 --> 00:08:41.920
we followed with that portfolio items list.
168
00:08:41.920 --> 00:08:46.240
So useEffect takes in a function as the argument,
169
00:08:46.240 --> 00:08:49.627
and inside of this function, I'm gonna say,
170
00:08:49.627 --> 00:08:51.390
if or actually let me store it
171
00:08:51.390 --> 00:08:52.950
just to make it a little easier to read.
172
00:08:52.950 --> 00:08:55.420
Let me create a token variable.
173
00:08:55.420 --> 00:09:00.420
So I'm gonna say const token equals localStorage.getItem,
174
00:09:04.240 --> 00:09:07.210
and then let's get the name of that token.
175
00:09:07.210 --> 00:09:09.870
I'm opening a switch to the admin login,
176
00:09:09.870 --> 00:09:14.100
and that is devCamp underscore space
177
00:09:14.100 --> 00:09:16.557
underscore secure underscore token.
178
00:09:16.557 --> 00:09:17.927
I'm just gonna copy that.
179
00:09:17.927 --> 00:09:19.890
And the reason why I copied that,
180
00:09:19.890 --> 00:09:22.180
is because I have had plenty of times
181
00:09:22.180 --> 00:09:25.100
where I've been working been going really fast,
182
00:09:25.100 --> 00:09:26.630
not really paying attention,
183
00:09:26.630 --> 00:09:29.620
and I would type the wrong token name,
184
00:09:29.620 --> 00:09:33.600
and even though the rest of my code was all built properly,
185
00:09:33.600 --> 00:09:35.450
nothing would work and is because,
186
00:09:35.450 --> 00:09:38.300
I was performing the wrong type of lookup.
187
00:09:38.300 --> 00:09:40.140
So it's always a good idea to make sure
188
00:09:40.140 --> 00:09:41.880
that that is correct.
189
00:09:41.880 --> 00:09:45.970
So I'm saying that I'm looking to get this item,
190
00:09:45.970 --> 00:09:49.960
and then store it in this variable here.
191
00:09:49.960 --> 00:09:53.500
So what I wanna do now I don't wanna just call checklogin,
192
00:09:53.500 --> 00:09:56.020
because they're gonna be plenty of times,
193
00:09:56.020 --> 00:09:58.360
where there's not gonna be a token here.
194
00:09:58.360 --> 00:10:01.379
So instead, I'm gonna say In useEffect,
195
00:10:01.379 --> 00:10:03.480
I'm gonna say if token.
196
00:10:03.480 --> 00:10:08.360
So if it found a token, then I want to call checklogin,
197
00:10:08.360 --> 00:10:10.930
and pass in the token as an argument.
198
00:10:10.930 --> 00:10:13.280
Now lastly, at the very end here,
199
00:10:13.280 --> 00:10:16.960
right after the curly brackets, add a comma,
200
00:10:16.960 --> 00:10:20.860
and then pass in the brackets here,
201
00:10:20.860 --> 00:10:24.590
so that this only runs one time.
202
00:10:24.590 --> 00:10:29.120
Hit Save, and we'll see if this is working.
203
00:10:29.120 --> 00:10:32.830
So I'm gonna open up the console here.
204
00:10:32.830 --> 00:10:37.830
And so hit refresh, and I'm not logged in right now.
205
00:10:38.590 --> 00:10:40.900
So we shouldn't actually see anything
206
00:10:40.900 --> 00:10:42.240
and we don't so that's good.
207
00:10:42.240 --> 00:10:44.330
So nothing has been triggered yet.
208
00:10:44.330 --> 00:10:48.627
Now let's go to the admin login.
209
00:10:48.627 --> 00:10:52.420
So I'm gonna go admin dash login page.
210
00:10:52.420 --> 00:10:57.420
And I'm gonna type in some an account.
211
00:11:00.680 --> 00:11:03.870
Okay, so I hit login here.
212
00:11:03.870 --> 00:11:07.413
And now let me just go back to the home page,
213
00:11:09.530 --> 00:11:13.770
and look at that right down here at the bottom.
214
00:11:13.770 --> 00:11:16.370
So now if you click on that,
215
00:11:16.370 --> 00:11:20.440
you can see that I have a client and this client object,
216
00:11:20.440 --> 00:11:23.450
I'll spread this out so you can see it.
217
00:11:23.450 --> 00:11:28.450
So because I logged in, and then I hit refresh,
218
00:11:28.610 --> 00:11:30.717
then what happened is we went out
219
00:11:30.717 --> 00:11:33.730
and we got the correct data.
220
00:11:33.730 --> 00:11:36.430
So here we have our client,
221
00:11:36.430 --> 00:11:38.910
we have all of the client data
222
00:11:38.910 --> 00:11:43.910
that got sent back in so that means that we are logged in.
223
00:11:44.010 --> 00:11:47.040
So all of this is working really nicely.
224
00:11:47.040 --> 00:11:50.380
This means that we are making our API call,
225
00:11:50.380 --> 00:11:54.280
we are receiving back data to see if we're logged in or not,
226
00:11:54.280 --> 00:11:55.950
and when we weren't logged in,
227
00:11:55.950 --> 00:11:58.630
we didn't get anything which is exactly what we want.
228
00:11:58.630 --> 00:12:00.500
But when we were like logged in,
229
00:12:00.500 --> 00:12:04.530
so when that token was there, and it was valid,
230
00:12:04.530 --> 00:12:07.290
we received the data that we were looking for.
231
00:12:07.290 --> 00:12:10.170
So that's perfect that's exactly what we're looking for.
232
00:12:10.170 --> 00:12:13.690
Now, how do we wire this up so that,
233
00:12:13.690 --> 00:12:18.690
this is logged in value will be updated properly?
234
00:12:18.750 --> 00:12:23.570
Well, what we can do is inside of our response,
235
00:12:23.570 --> 00:12:25.500
we can update our state.
236
00:12:25.500 --> 00:12:30.290
So here, if you remember back, the data look like this.
237
00:12:30.290 --> 00:12:35.190
So we're gonna say if response.data.client,
238
00:12:35.190 --> 00:12:38.910
so the only way that we're gonna get response data client,
239
00:12:38.910 --> 00:12:41.280
is if the user actually is logged in.
240
00:12:41.280 --> 00:12:43.600
So we're gonna say, if that's true,
241
00:12:43.600 --> 00:12:48.230
then I want you to set is logged in to true.
242
00:12:48.230 --> 00:12:51.150
And that's all we're gonna have to make available
243
00:12:51.150 --> 00:12:54.310
'cause we're already making the state available.
244
00:12:54.310 --> 00:12:56.700
So we're parsing in that data right here,
245
00:12:56.700 --> 00:12:59.770
and that's what we're reading here on the homepage.
246
00:12:59.770 --> 00:13:02.050
So I'm gonna hit Save here.
247
00:13:02.050 --> 00:13:04.430
And now let's watch, and did you see that?
248
00:13:04.430 --> 00:13:07.270
It started off as false because in the beginning,
249
00:13:07.270 --> 00:13:10.620
that is the default behavior is false.
250
00:13:10.620 --> 00:13:15.530
And then it called the API as soon as we got verification
251
00:13:15.530 --> 00:13:18.900
that we were an admin logged in user,
252
00:13:18.900 --> 00:13:22.300
then is updated throughout the entire application.
253
00:13:22.300 --> 00:13:25.680
So any other page, anything that needed to know
254
00:13:25.680 --> 00:13:27.380
if the user is logged in or not,
255
00:13:27.380 --> 00:13:29.370
would then get updated.
256
00:13:29.370 --> 00:13:30.870
So this is working really nicely.
257
00:13:30.870 --> 00:13:34.400
We now have a guard a way of checking to see,
258
00:13:34.400 --> 00:13:38.180
if you are logged in as an admin or not.
259
00:13:38.180 --> 00:13:40.370
So this is working really nice.
260
00:13:40.370 --> 00:13:42.180
In the next guide, what we're gonna do,
261
00:13:42.180 --> 00:13:46.320
is we are going to update our login process,
262
00:13:46.320 --> 00:13:48.610
so that after we've logged in,
263
00:13:48.610 --> 00:13:52.870
we can automatically wait and update
264
00:13:52.870 --> 00:13:57.870
our is logged in status and we can checklogin right away,
265
00:13:58.020 --> 00:14:01.470
and we can also redirect the user to the homepage.
266
00:14:01.470 --> 00:14:03.600
So what this is gonna do is,
267
00:14:03.600 --> 00:14:06.740
if you remember back just a few moments ago,
268
00:14:06.740 --> 00:14:09.460
when I logged in, I had to hit refresh,
269
00:14:09.460 --> 00:14:11.910
in order to get our updated value.
270
00:14:11.910 --> 00:14:14.390
Well, that's not really a great user experience.
271
00:14:14.390 --> 00:14:16.050
So in the next guide, what we're gonna do,
272
00:14:16.050 --> 00:14:18.640
is we're gonna walk through how we can automate
273
00:14:18.640 --> 00:14:21.820
that process so that as soon as the user
274
00:14:21.820 --> 00:14:23.590
successfully logs in,
275
00:14:23.590 --> 00:14:26.127
we're gonna add our local storage token,
276
00:14:26.127 --> 00:14:29.520
we are going to call our checklogin function
277
00:14:29.520 --> 00:14:31.030
from a different component,
278
00:14:31.030 --> 00:14:33.123
and then we're gonna redirect the user.