WEBVTT

00:00.000 --> 00:00.270
Okay.

00:00.300 --> 00:06.930
We're going to add another couple of endpoints in here because with our API identity endpoints we can

00:06.930 --> 00:08.280
get user information.

00:08.280 --> 00:13.800
And if we do take a look back at the documentation and take a look at one of these other endpoints,

00:13.800 --> 00:15.870
the Get manage info.

00:15.900 --> 00:21.090
Then we can go and get the information about the user who's currently logged in the user we have a cookie

00:21.090 --> 00:23.370
for and find out their email address.

00:23.370 --> 00:25.320
And is the email confirmed?

00:25.350 --> 00:30.180
Okay, that's fine, but perhaps we want to send more information back to the client, especially when

00:30.180 --> 00:35.790
it comes to looking at the roles a bit later on, because we'd also like that information to come back

00:35.790 --> 00:37.620
from an info endpoint.

00:37.830 --> 00:44.130
And if we go and test that endpoint, and we take a look at the get default user info that I've got

00:44.160 --> 00:51.300
here, and we take a look at the API manage info that's going to call that endpoint for the current

00:51.300 --> 00:51.660
user.

00:51.660 --> 00:58.200
We're logged in as the user that we have a cookie for, which in this case it's going to be Tom because

00:58.200 --> 01:00.150
that's the one I just clicked on to sign in.

01:00.150 --> 01:01.260
And I click send.

01:01.290 --> 01:05.430
Then we can see that we get Tom's email back and that email is not confirmed.

01:05.460 --> 01:08.190
Of course, because it's not a valid email anyway.

01:08.340 --> 01:15.690
If I log in as a different user and let's go back to Bob, for instance, and click send and we get

01:15.690 --> 01:20.340
the default user info again, what we should get this time is Bob's email address coming back.

01:20.340 --> 01:20.940
So great.

01:20.970 --> 01:24.600
Our authentication system is working.

01:24.600 --> 01:29.520
We can log in using the user that we have registered and one of the ones that we've seeded.

01:29.730 --> 01:32.730
But I'd like to get a bit more information back about the user.

01:32.730 --> 01:35.790
When we do log in and we get a cookie, that's all we get.

01:35.820 --> 01:41.370
We can't interrogate that cookie from our react client because it's an HTTP only cookie, which means

01:41.370 --> 01:43.530
we cannot access that from JavaScript.

01:43.530 --> 01:48.540
So whatever happens when a user logs in, we're going to have to call another endpoint.

01:48.540 --> 01:54.750
And since the one that API endpoints has provided to us doesn't give us much information and we cannot

01:54.750 --> 01:59.040
customize this, then we'll create our own endpoint to get information back.

01:59.070 --> 02:05.790
Also, when it comes to removing the cookie from the browser, then the API endpoint does not actually

02:05.790 --> 02:07.910
provide us with a log logout endpoint.

02:07.910 --> 02:10.850
So we need to do something for that as well.

02:10.850 --> 02:13.250
So let's go back to VS code.

02:13.250 --> 02:15.260
And we'll go back to our account controller.

02:15.260 --> 02:18.380
And we'll add another couple of things inside here.

02:18.380 --> 02:20.900
So we're going to have an HTTP get.

02:20.900 --> 02:24.200
And this is going to be for user info.

02:25.940 --> 02:30.560
And we'll give this public async task.

02:31.520 --> 02:34.430
And it's going to be an action result.

02:34.640 --> 02:39.830
And we'll use Get user info as the method name.

02:39.830 --> 02:44.270
We won't take any parameters because we can get the user from the cookie.

02:44.300 --> 02:50.870
Now it would be tempting to say let's make this an authorized endpoint.

02:50.870 --> 02:57.200
And if we wanted one of these endpoints to only be able to be called if the user was authenticated,

02:57.200 --> 03:01.490
then we could use authorize as an attribute inside here.

03:02.960 --> 03:05.810
And could we do that for this endpoint?

03:05.810 --> 03:06.800
Yes we could.

03:06.830 --> 03:14.040
And what would happen if an anonymous user called this end point, then this would return a 401 unauthorized.

03:14.070 --> 03:17.220
And we will use this for other endpoints later on.

03:17.220 --> 03:19.200
But we're not going to use it for this one.

03:19.890 --> 03:25.230
And the reason being is that when our application starts up, our react application starts up, either

03:25.230 --> 03:28.830
a user refreshes the browser or they've gone away and come back.

03:28.860 --> 03:33.120
Then one of the things we'd want to do is persist their login.

03:33.120 --> 03:38.760
If they've got a cookie in their browser, we would like to persist their login status now, because

03:38.790 --> 03:44.130
our react client doesn't maintain a connection with our API, the only way we can do that is by using

03:44.130 --> 03:49.740
the cookie in the browser to go and do something on our API, and we'll use it to go and get the user

03:49.740 --> 03:50.490
info.

03:50.490 --> 03:56.820
But because we cannot use the cookies in the browser from our react application, we cannot even check

03:56.820 --> 04:00.510
to see if there is a cookie related to authentication in the browser.

04:00.510 --> 04:04.320
The only way we can find out is by making a request to the API.

04:04.350 --> 04:09.690
Now, when our application or when I use a refreshes the page, I don't really want to.

04:09.720 --> 04:14.990
If they're just logged in anonymously or not logged in, I should say I don't really want to display

04:14.990 --> 04:20.450
a toast every time they refresh the browser saying, hey, you're not authenticated or give them an

04:20.450 --> 04:20.870
error.

04:20.870 --> 04:22.340
401 error.

04:22.490 --> 04:24.200
I'd rather that not happen.

04:24.200 --> 04:30.590
So for this one, we'll do not that we won't make this an authorized endpoint, and we'll check a different

04:30.590 --> 04:34.430
way to see if we do want to send back any information about the user.

04:34.460 --> 04:38.360
Now, one of the things we get inside our controller is a user object.

04:38.360 --> 04:44.210
And if we use user period then we can see the different information we can get about this user.

04:44.210 --> 04:51.920
And if we use the user identity then one of its properties is is authenticated.

04:52.130 --> 04:58.640
And when a user makes a request to this endpoint, then one of the features of an API controller is

04:58.640 --> 05:00.980
it populates this user object.

05:01.070 --> 05:04.640
If the user posts a cookie with the request.

05:04.640 --> 05:11.930
So this controller endpoint will be able to check to see if this user is authenticated, and we'll check

05:11.930 --> 05:15.710
to see if the user is not authenticated by making that equal to false.

05:15.710 --> 05:22.650
And I'll just use the optional property here and if it is false, then we're not going to return unauthorized.

05:22.650 --> 05:26.610
We're simply going to return no content, which sends back a 204.

05:26.610 --> 05:32.850
No content, which is a successful request, which means it will not spit out an error on our client's

05:32.850 --> 05:33.810
browser.

05:34.710 --> 05:38.130
If they are authenticated, then we're going to return some user information.

05:38.130 --> 05:41.880
So I'll use var user equals and then await.

05:41.910 --> 05:44.130
We'll use our sign in manager again.

05:44.160 --> 05:46.170
Again we'll get the user manager.

05:46.170 --> 05:49.560
And we'll use the Get user async method.

05:49.560 --> 05:53.520
And we'll pass in the user and user with a capital U.

05:53.520 --> 05:59.700
Because this takes what is if I hover over the user then this is a claims principal.

05:59.700 --> 06:04.230
And the get user async method is asking for a claims principal.

06:04.230 --> 06:09.780
So we can just use what we get from our controller there for our user in lowercase u.

06:11.160 --> 06:16.920
And if the user is equal to null at this point, then we are going to return unauthorized.

06:16.920 --> 06:23.130
But our user should not be null at this point if we do have a claims principle for that user.

06:23.160 --> 06:28.110
This is really just for our compiler, so we don't get any errors when we try and use the user, because

06:28.110 --> 06:29.730
this could possibly be null.

06:29.730 --> 06:32.340
And then we'll get hold of the roles for the user.

06:32.340 --> 06:37.170
So once again we'll use the await sign in manager and the user manager.

06:37.170 --> 06:42.930
And then we'll use the Get roles async method and pass in the user.

06:43.500 --> 06:46.470
And then from this we'll return okay.

06:46.500 --> 06:48.420
And we won't create a type for this.

06:48.420 --> 06:52.140
We'll just create what's referred to as an anonymous object.

06:52.140 --> 06:53.250
So I'll say new.

06:53.250 --> 06:56.700
And on the next line I'll open curly brackets for an object.

06:56.700 --> 06:59.160
And we'll specify user dot email.

06:59.400 --> 07:05.430
The user dot username will just return that as well just as an example of returning things.

07:05.430 --> 07:11.640
And we'll also specify roles equals user dot equals roles.

07:12.900 --> 07:15.600
And close this off with a semicolon.

07:15.630 --> 07:19.320
We'll also create another endpoint inside here as well.

07:19.320 --> 07:21.660
This is going to be an HTTP post.

07:22.080 --> 07:30.450
And we will give it a parameter of log out and we'll say public async task.

07:31.410 --> 07:34.800
And again we'll just use Actionresult here without a type.

07:34.800 --> 07:37.200
And we'll just call this method log out.

07:37.230 --> 07:43.140
And inside here we'll use await and sign in manager.

07:43.140 --> 07:49.380
And this is the reason for using sign in manager inside this controller rather than just the user manager

07:49.410 --> 07:54.000
because this one has a sign out async method.

07:54.000 --> 07:59.100
And if we take a look at what this does well, it doesn't give us much detail.

07:59.100 --> 08:01.860
It signs the current user out of the application.

08:01.860 --> 08:07.290
But what it also does is it removes the cookie from the user's browser as well.

08:07.290 --> 08:08.580
We can't do this client side.

08:08.580 --> 08:12.570
We cannot touch the cookie in the client's browser from the react application.

08:12.570 --> 08:17.280
We have to do everything server side for that, and that's what this method does.

08:17.280 --> 08:23.040
And then I will return no content from this because it's an HTTP request.

08:23.070 --> 08:25.970
We have to make an HTTP Response.

08:26.060 --> 08:29.390
So let's open up the terminal.

08:29.390 --> 08:32.270
And too many warnings there for my liking.

08:32.270 --> 08:38.600
I'm just going to restart the API controller and make sure it starts cleanly without any warnings.

08:38.600 --> 08:43.100
And we'll go back and let's take a look at the get custom user info this time.

08:43.280 --> 08:46.010
So it's going to API account user info.

08:46.010 --> 08:47.030
Click send.

08:47.030 --> 08:51.560
And we can see that we've got the email of Bob at test.com, same as the username.

08:51.560 --> 08:54.290
And then we've got our array of roles.

08:54.290 --> 08:57.980
And Bob is only in one role which is the member.

08:58.430 --> 09:04.970
And if we take a look at the equivalent for the admin, there's a login method here for admin, which

09:04.970 --> 09:06.230
is just the email.

09:06.230 --> 09:13.070
As admin I'm going to say email at test.com and the same password and click send.

09:13.100 --> 09:14.600
We get the 200 okay.

09:14.600 --> 09:20.600
And if we take a look at the custom user info then we should find that the admin is in the member and

09:20.600 --> 09:21.860
the admin role.

09:22.730 --> 09:23.630
Excellent.

09:23.630 --> 09:28.460
And just to finish off, actually there's a couple of requests in here to make sure that we cannot register

09:28.460 --> 09:34.440
To a user with a duplicate username or email address.

09:34.440 --> 09:38.580
I don't need that username there, so I'm just going to remove that and click send.

09:38.760 --> 09:43.770
And we can see that the email bob at test.com is already in use.

09:43.770 --> 09:46.740
And we get the same for the duplicate username as well.

09:46.740 --> 09:47.520
That's fine.

09:47.520 --> 09:49.530
I'm going to say that's okay for our response.

09:49.530 --> 09:53.640
And we've already seen what happens if we try and use a weak password.

09:53.640 --> 09:55.620
Again, I don't need that username there.

09:55.770 --> 09:57.270
And click send.

09:57.270 --> 10:01.350
And then we get the password validation coming back here as well.

10:01.350 --> 10:01.950
So great.

10:01.950 --> 10:05.430
That's our identity specific endpoints taken care of.

10:05.430 --> 10:09.750
I've got a couple of others down here in this postman requests for this section.

10:09.750 --> 10:12.690
And that's to get an address and update an address.

10:12.690 --> 10:16.770
It's not something we're going to need immediately because it's more related to our checkout.

10:16.770 --> 10:19.680
But we'll also cover adding these endpoints inside here.

10:19.680 --> 10:26.280
Since we're working with our API controller, we'll also take a look at how we can populate a user's,

10:26.310 --> 10:30.600
let's call it shipping address and retrieve it as well.

10:30.600 --> 10:32.760
And we'll take a look at that next.
