1
00:00:05,420 --> 00:00:11,810
Welcome back in this lecture we're going to walk through the steps to have rest API authorization.

2
00:00:11,990 --> 00:00:18,830
We can use the flask JWT or Jason Webb token library to require authorization before being able to create

3
00:00:18,890 --> 00:00:20,650
a rest API call.

4
00:00:20,660 --> 00:00:26,330
Users will need to provide a username and password to an authentication page then they'll receive a

5
00:00:26,330 --> 00:00:30,280
key or token that they can attach to the rest of their API calls.

6
00:00:30,290 --> 00:00:35,950
That way we can make sure only authorized users are able to access our API.

7
00:00:35,950 --> 00:00:41,230
Now we're going to need to install the flask JWT library and you can do that simply command line with

8
00:00:41,230 --> 00:00:44,730
Pipp install flask cache JWT.

9
00:00:44,740 --> 00:00:46,450
OK let's get started.

10
00:00:46,450 --> 00:00:51,130
We're going to be working with the same file as last time but we're going to add authorizations to certain

11
00:00:51,130 --> 00:00:53,680
API calls right before we get started.

12
00:00:53,680 --> 00:00:59,360
As I mentioned you're going to need to install flask dash JWT.

13
00:00:59,560 --> 00:01:03,310
So already have it installed so go ahead and make sure you have it installed as well.

14
00:01:03,440 --> 00:01:08,600
And we're going to create two more dot pite files inside of this flask example folder.

15
00:01:08,840 --> 00:01:12,670
We're going to create one file called Secure underscore check.

16
00:01:12,670 --> 00:01:17,410
Technically you can call it whatever you want but this is going to have two functions one for authentication

17
00:01:17,680 --> 00:01:22,140
and another one for identity and we'll have one more file.

18
00:01:22,300 --> 00:01:25,360
And this one is going to be called user dot pi.

19
00:01:25,360 --> 00:01:31,000
So as we've seen before we can store our own user class inside of models.

20
00:01:31,000 --> 00:01:35,940
And typically that's how you would actually perform a authorisations storage.

21
00:01:35,950 --> 00:01:38,830
But for our use case we're kind of keep things simple here.

22
00:01:38,980 --> 00:01:44,380
So inside this user that PI file what we're going to do is we're going to create a really simple user

23
00:01:44,380 --> 00:01:48,120
class and then we're going to import it into our simple API.

24
00:01:48,120 --> 00:01:51,960
So say class user.

25
00:01:52,150 --> 00:01:55,580
And then these are users that are inside our database.

26
00:01:55,930 --> 00:02:00,980
So we're going to say users have an ID a user name and password.

27
00:02:01,150 --> 00:02:02,890
Very similar to what we've done in the past.

28
00:02:03,280 --> 00:02:11,740
And then we'll just say self-id is equal to ID self-taught user name is equal to user name and then

29
00:02:12,160 --> 00:02:17,530
self-taught password is equal to password and you can build on top of this given what we already know

30
00:02:17,530 --> 00:02:20,060
about flask authorization flask log in.

31
00:02:20,290 --> 00:02:22,810
You can hash the passwords and keep it more secure.

32
00:02:22,810 --> 00:02:27,430
We're doing a really simplified approach right now and then just in case we ever want to print out a

33
00:02:27,430 --> 00:02:28,200
user.

34
00:02:28,420 --> 00:02:38,250
We'll go ahead and make a string method here that just returns user ID and then we'll say ID again using

35
00:02:38,250 --> 00:02:40,480
f string notation here.

36
00:02:40,560 --> 00:02:43,230
Not technically not necessary but it's helpful for debugging.

37
00:02:43,230 --> 00:02:44,850
They can print out the users.

38
00:02:44,850 --> 00:02:45,310
OK.

39
00:02:45,510 --> 00:02:50,090
So we definitely seen something like this before and now it's in this special user that pi.

40
00:02:50,100 --> 00:02:54,210
So now we're going to do is we're going to come over to your to secure check.

41
00:02:54,600 --> 00:02:58,950
So a secure underscore checked up pi and you can technically call this file whatever you want.

42
00:02:58,950 --> 00:03:02,950
Let me give ourselves a little more room here and we're to create some users.

43
00:03:03,030 --> 00:03:09,450
So I can to say from user import user essentially from that user profile import that user class and

44
00:03:09,450 --> 00:03:16,410
let's create a list of users so will have a list and let's create a user.

45
00:03:16,440 --> 00:03:22,230
We'll give them I.D. one will go ahead and say this user is Jose and then we'll say my password is the

46
00:03:22,230 --> 00:03:23,280
password.

47
00:03:23,280 --> 00:03:27,080
And again you'd probably be storing these users in a database somewhere.

48
00:03:27,210 --> 00:03:29,110
But we're keeping things simple for now.

49
00:03:29,610 --> 00:03:31,410
So say create one more user.

50
00:03:31,530 --> 00:03:36,960
Let's have this user be Mimi and then we'll have their passerby's secret.

51
00:03:37,340 --> 00:03:37,780
OK.

52
00:03:38,010 --> 00:03:44,370
So we have this list of users and then we're going to do is create some mapping in order to quickly

53
00:03:44,370 --> 00:03:48,150
access users based off their I.D. are based off their name.

54
00:03:48,240 --> 00:03:54,850
So in order to do this and essentially directly from the documentation for flask JWT they have this

55
00:03:54,850 --> 00:03:56,110
kind of simple example.

56
00:03:56,380 --> 00:04:08,590
What they do is they say you dot user name Colan you for you in users and this may be a comprehension

57
00:04:08,590 --> 00:04:10,270
style that you haven't seen before.

58
00:04:10,390 --> 00:04:15,550
But essentially this is a dictionary comprehension that's creating a dictionary that's mapping these

59
00:04:15,550 --> 00:04:18,570
users to a user name.

60
00:04:18,580 --> 00:04:21,040
So we're saying is for you end users.

61
00:04:21,040 --> 00:04:27,400
So we have this list and for every user here I'm going to grab their user name because remember that's

62
00:04:27,460 --> 00:04:28,930
literally an attribute of theirs.

63
00:04:28,960 --> 00:04:34,420
It's going to grab their username and then link it to that actual specific user object.

64
00:04:34,420 --> 00:04:39,100
So then if we actually have user name and table what it should look like is Jose.

65
00:04:39,100 --> 00:04:43,030
And then this user Mimi and then this user object.

66
00:04:43,030 --> 00:04:46,000
So that's going to allow us to look things up by the username.

67
00:04:46,000 --> 00:04:52,110
It's going to be able to then say user name table and then look up Jose in order to get back this user

68
00:04:52,110 --> 00:04:53,310
name object.

69
00:04:53,320 --> 00:05:00,400
OK so have a user name table and then I'm also going to have user id table and it's the same concept

70
00:05:00,580 --> 00:05:05,000
except I will say you ID and then say you.

71
00:05:05,210 --> 00:05:08,590
For you in users the exact same thing.

72
00:05:08,580 --> 00:05:12,950
Building a dictionary here based off the ID for every user.

73
00:05:13,170 --> 00:05:13,720
OK.

74
00:05:13,890 --> 00:05:17,450
So if you haven't seen those sort of comprehension before it's just an easy way to do it.

75
00:05:17,460 --> 00:05:20,170
You could also do this manually for a for loop if you wanted to.

76
00:05:20,820 --> 00:05:23,250
And then we have to do is create two function functions.

77
00:05:23,250 --> 00:05:26,100
One is authenticate and the other one is identity.

78
00:05:26,370 --> 00:05:31,560
Authenticate is going to take a user name and password check to make sure that username and password

79
00:05:31,650 --> 00:05:33,650
match someone in our list.

80
00:05:33,780 --> 00:05:38,190
And you would do the same thing with your database and then it's going to return the user.

81
00:05:38,220 --> 00:05:41,720
So say authenticates let me collapses.

82
00:05:41,750 --> 00:05:49,900
We get a little more room here takes in a username and password and then the main idea here is that

83
00:05:50,200 --> 00:05:54,470
this function should check if user exists.

84
00:05:56,440 --> 00:05:58,790
If so return user.

85
00:05:59,230 --> 00:06:04,420
So in our case for instance for storing it as a symbolist and we already have this nice user name table

86
00:06:04,420 --> 00:06:12,950
as a quick look up unless a user is equal to username it's true it's an equal sign user name underscore

87
00:06:12,950 --> 00:06:14,100
table.

88
00:06:14,570 --> 00:06:19,780
And then I can just say get user name.

89
00:06:19,940 --> 00:06:28,340
And the reason I'm using get instead of just a call such as user name underscore a table and then say

90
00:06:28,940 --> 00:06:30,140
user name.

91
00:06:30,140 --> 00:06:36,980
Technically this would work but if you try calling a key that isn't in the dictionary will return an

92
00:06:36,980 --> 00:06:37,630
error.

93
00:06:37,850 --> 00:06:43,070
So what I can do is instead of doing a call like this with the dictionary that we created up here what

94
00:06:43,070 --> 00:06:50,180
I can do is say Dot get username comma with another option to return in case we actually don't find

95
00:06:50,180 --> 00:06:50,950
that user.

96
00:06:51,170 --> 00:06:52,370
So I can say none.

97
00:06:52,370 --> 00:06:57,960
And this basically says hey try to grab that user name key from the username table which is just the

98
00:06:58,400 --> 00:07:00,260
dictionary that we created right here.

99
00:07:00,260 --> 00:07:02,560
If you can't find it username that does return on.

100
00:07:02,570 --> 00:07:03,920
So that's what that's doing.

101
00:07:04,100 --> 00:07:10,340
And then we'll say if user and the password matches that particular user's password so equal sequel's

102
00:07:11,060 --> 00:07:16,830
user password then what we're going to do is return the user.

103
00:07:16,940 --> 00:07:22,600
OK so again all we're doing here with authenticate is later on we're going to use this function.

104
00:07:22,600 --> 00:07:28,330
The person using the rest API is going to provide a username and password then we'll look up that username

105
00:07:28,450 --> 00:07:34,200
if it exists then we'll say the password they provide it matches and then return that user if that user

106
00:07:34,220 --> 00:07:36,700
doesn't exist and we just mark user as none.

107
00:07:36,700 --> 00:07:41,110
So if none that immediately fails and then we're not actually gonna return a user.

108
00:07:41,110 --> 00:07:42,720
So they didn't get authenticated.

109
00:07:42,760 --> 00:07:47,120
OK then we have one more function to create and that's going to be an identity function.

110
00:07:47,260 --> 00:07:54,040
And basically we're going to be copying the structure from the documentation for flask JWT because the

111
00:07:54,040 --> 00:07:57,920
JWT object we're going to call requires a function in this format.

112
00:07:57,940 --> 00:07:59,670
So sure more details on it.

113
00:07:59,660 --> 00:08:02,380
You can take a look at the Flast JWT documentation.

114
00:08:02,380 --> 00:08:06,060
In fact they basically have the full QuickStart example that we're going through.

115
00:08:06,100 --> 00:08:11,140
It's a very similar example to what we're doing here except it's kind of all in one file with the authentication

116
00:08:11,470 --> 00:08:12,460
and the identity.

117
00:08:12,460 --> 00:08:16,500
And essentially what we want to do is we need to grab this function right here.

118
00:08:16,690 --> 00:08:23,120
So what it does is we zoom in here it takes in the payload grabs the identity which is going to be the

119
00:08:23,120 --> 00:08:29,650
user id and then just grabs up to gular entry in the User ID table and we created it using essentially

120
00:08:29,650 --> 00:08:32,790
the same terminology to that here user id for you and users.

121
00:08:33,010 --> 00:08:37,970
And obviously this could be a call to your model or your database instead.

122
00:08:37,990 --> 00:08:42,220
So let's come back here and we're going to fill out that function ourselves centrally the exact same

123
00:08:42,220 --> 00:08:47,800
thing and it'll make sense in a little bit why it has to be in this particular structure because both

124
00:08:47,860 --> 00:08:53,590
authenticate and identity will be passed in to the JWT call that we're going to see in the simple API

125
00:08:53,590 --> 00:08:54,400
file.

126
00:08:54,400 --> 00:09:00,970
So here we're going to say user ID is equal to payload and they're going to grab identity from that

127
00:09:00,970 --> 00:09:10,370
payload and then when a return user id table gets an old say user id Khama none.

128
00:09:10,790 --> 00:09:14,280
OK so basically doesn't really change anything there from the documentation.

129
00:09:14,530 --> 00:09:18,020
But again what we're doing here is a really simplified example.

130
00:09:18,310 --> 00:09:21,600
And it's not a whole lot more to connect this to your own database.

131
00:09:21,600 --> 00:09:27,670
You'd have your own database of your own models and what you do is for these commands of user name table

132
00:09:27,670 --> 00:09:32,590
gets or user id table get these would just be calls to that particular database so you would say import

133
00:09:32,590 --> 00:09:37,930
user from model or from models import user and you want to be dealing with this list or these tables

134
00:09:37,930 --> 00:09:38,590
right here.

135
00:09:38,620 --> 00:09:40,910
It's kind of just a mimic those models themselves.

136
00:09:41,190 --> 00:09:41,630
OK.

137
00:09:41,830 --> 00:09:44,580
So we have the security check functionality ready to go.

138
00:09:44,620 --> 00:09:47,720
All we do now is come back to simple API.

139
00:09:48,160 --> 00:09:54,630
We'll come to the very top and we're going to do a couple of more imports we'll say from secure check

140
00:09:54,660 --> 00:09:59,990
or whatever we happen to call that file import authenticate an identity.

141
00:10:00,010 --> 00:10:10,700
Those are two functions are created and they will say from flask underscore JWT import JWT and then

142
00:10:10,970 --> 00:10:13,760
JWT required.

143
00:10:13,760 --> 00:10:18,250
So JWT is essentially going to be the Flash version of this API.

144
00:10:18,470 --> 00:10:24,710
So what you do is after you create your flask and after you create your app you create a W.T. object

145
00:10:24,860 --> 00:10:33,080
and say JWT passen your app and then passen the authenticate function and then pasand the identity function.

146
00:10:33,080 --> 00:10:38,280
So because JWT expects and authenticate an identity function that's where we had to create them in a

147
00:10:38,420 --> 00:10:39,890
kind of specific format.

148
00:10:39,970 --> 00:10:42,160
Over here it's secure check pie.

149
00:10:42,500 --> 00:10:48,160
So we created those two functions and then we also passed in our app to JWT because we're going to basically

150
00:10:48,160 --> 00:10:54,500
be using a kind of a form style configuration where you do is after we create our app we need to add

151
00:10:54,500 --> 00:10:56,410
one more line which we've seen before.

152
00:10:56,510 --> 00:11:01,490
It's app config and then we need to set up our secret key.

153
00:11:01,630 --> 00:11:05,890
So we've seen this before especially when talking about forms and you can essentially call this whatever

154
00:11:05,890 --> 00:11:06,260
you want.

155
00:11:06,280 --> 00:11:09,110
So I'll say my secret key.

156
00:11:09,300 --> 00:11:16,470
OK now you're wondering well how do I actually make certain rest API calls require authentication.

157
00:11:16,470 --> 00:11:20,530
Well that's where this JWT underscore required comes into play.

158
00:11:20,550 --> 00:11:26,100
In fact all you need to do is once you set up your authenticate an identity function based on how you're

159
00:11:26,100 --> 00:11:31,830
storing your user information and you set up your secret key if you want to make sure something requires

160
00:11:31,890 --> 00:11:39,200
authentication such as a call or a post call then you just highlight it with a decorator.

161
00:11:39,210 --> 00:11:43,020
So for example here we have the get for all the names in the database.

162
00:11:43,020 --> 00:11:49,700
I just say at JWT underscore required open and princes and that's it.

163
00:11:49,710 --> 00:11:55,220
Now if you want to grab all the names for puppies then you're going to need to provide your username

164
00:11:55,250 --> 00:11:57,020
password and get authenticated.

165
00:11:57,210 --> 00:12:01,170
However if you want to delete a single puppy post a single puppy or get a single puppy.

166
00:12:01,170 --> 00:12:03,590
Right now we're not requiring authentication for that.

167
00:12:03,690 --> 00:12:09,360
So you can see how easy it is to you know add and subtract authentication to whatever functionality

168
00:12:09,360 --> 00:12:14,400
you want because maybe you want people to be able to get anything but you only want authorized users

169
00:12:14,400 --> 00:12:19,410
to be able to post things so that decorator functionality really makes the whole thing a lot easier.

170
00:12:19,620 --> 00:12:21,940
And everything else essentially stays the same.

171
00:12:21,960 --> 00:12:24,280
So let's see if this all worked using postman.

172
00:12:24,300 --> 00:12:28,890
We're going to try to do is we're going to create two puppies into the list and then show you how you

173
00:12:28,890 --> 00:12:32,280
can get your username password authenticated with a key.

174
00:12:32,280 --> 00:12:36,180
So before we run postman we need to do is actually run our Web application.

175
00:12:36,360 --> 00:12:39,730
So here I'm going to say Python and I'm still calling this simple API.

176
00:12:39,780 --> 00:12:41,130
So we'll run that.

177
00:12:41,130 --> 00:12:42,020
There we go it's running.

178
00:12:42,030 --> 00:12:43,720
Now let's go ahead and go to postman.

179
00:12:44,030 --> 00:12:45,810
OK so here I am at postman.

180
00:12:45,960 --> 00:12:50,010
I'm going to post a couple more puppies.

181
00:12:50,010 --> 00:12:52,310
So let's go ahead and post Sam.

182
00:12:52,530 --> 00:12:53,750
Say send.

183
00:12:54,090 --> 00:12:55,250
And then we have named Sam.

184
00:12:55,290 --> 00:12:57,750
And let's go ahead and post Frankie again.

185
00:12:57,790 --> 00:13:01,200
Remember every time you run this because we're storing the puppies as a list you don't actually get

186
00:13:01,200 --> 00:13:02,640
saved.

187
00:13:02,910 --> 00:13:04,550
So we'll post Frankie as well.

188
00:13:04,950 --> 00:13:07,230
And so now I have Sam and Frankie.

189
00:13:07,290 --> 00:13:09,660
Now let's try to actually get all those puppies.

190
00:13:09,660 --> 00:13:14,710
Remember that we specifically required puppies with a Jason Webb token.

191
00:13:14,730 --> 00:13:20,100
So if I try to get the puppies and send this request notice it says hey requests does not contain an

192
00:13:20,100 --> 00:13:25,680
access token authorization required status code for 0 1 an authorized.

193
00:13:25,680 --> 00:13:28,240
So how do we actually get our authorization token.

194
00:13:28,470 --> 00:13:33,600
Well the first thing to do is register with the website to get a username and password so we can do

195
00:13:33,600 --> 00:13:34,010
that.

196
00:13:34,140 --> 00:13:39,140
A variety of ways on a template using class logon and everything is covered so far.

197
00:13:39,150 --> 00:13:43,200
Keep in mind we manually created 2 users in our users that pi file Jose and Mimi.

198
00:13:43,200 --> 00:13:44,460
So we'll be using them.

199
00:13:44,700 --> 00:13:50,440
So if we come back to our actual Of Pi I already know whoops I mean secure check.

200
00:13:50,600 --> 00:13:53,950
I already know that there's a user Jose whose password is my password.

201
00:13:54,000 --> 00:13:55,770
So that's what I'm going to log in with.

202
00:13:55,770 --> 00:14:03,770
So we actually log in as we go to our Web site and we're going to say Auth. so we never actually routed

203
00:14:03,770 --> 00:14:07,820
this you r l that gets created automatically with flask JWT.

204
00:14:07,820 --> 00:14:09,910
Again it's just for Slash a.

205
00:14:09,940 --> 00:14:10,860
Th.

206
00:14:11,090 --> 00:14:16,490
And then we're going to do here is in our header we're going to send a key and a value.

207
00:14:16,520 --> 00:14:26,610
So the key we provide is we say content type and then we're going to give a value of application forward

208
00:14:26,610 --> 00:14:33,210
slash Jaison because we're going to provide the content of our username and password as Jason.

209
00:14:33,210 --> 00:14:35,820
So we also need a change sort of get to post.

210
00:14:35,850 --> 00:14:41,760
So essentially we're sending or posting our username and password as Jasen to this authorization and

211
00:14:41,760 --> 00:14:43,360
we receive back a token.

212
00:14:43,530 --> 00:14:51,720
So the next step we need to do is click here where it says body and then we're going to select raw and

213
00:14:51,720 --> 00:14:57,060
then remember we already specified we're passing this in as Jason so we're going to set up our Jason

214
00:14:57,120 --> 00:15:01,770
which essentially looks like a python dictionary and we're going to set this up to have our username

215
00:15:01,770 --> 00:15:02,700
and password.

216
00:15:03,180 --> 00:15:16,040
So we'll say username Jose Khama password and we set it up as my password and then use the double quotes

217
00:15:16,040 --> 00:15:16,830
here.

218
00:15:16,880 --> 00:15:19,980
So once that's ready to go again in hetero's we have Content-Type.

219
00:15:20,000 --> 00:15:22,040
Application forward slash Jason.

220
00:15:22,070 --> 00:15:24,150
And then here in body we cook raw.

221
00:15:24,290 --> 00:15:26,210
We have user name Jose in my password.

222
00:15:26,310 --> 00:15:29,010
I remember we have post and we're sending this to us.

223
00:15:29,250 --> 00:15:32,490
And in case you messed up in this process we can't see these parameters.

224
00:15:32,510 --> 00:15:34,570
You can always just close this and start over again.

225
00:15:34,820 --> 00:15:37,290
But let's go ahead and send this and see what we get back.

226
00:15:38,790 --> 00:15:44,910
So now that I've sent that to off notice I get back this giant access token and I'm going to use this

227
00:15:44,910 --> 00:15:48,570
access token in order to now get all the puppies.

228
00:15:48,570 --> 00:15:54,740
So what I'm going to do is changes to get inless try reaching all those puppies again.

229
00:15:54,900 --> 00:16:00,390
But now what I'm going to do is in my request Anglia's say headers and it's sort of this content type

230
00:16:00,450 --> 00:16:07,530
application and said we're going to do is I'm going to create a header with an authorization key and

231
00:16:07,530 --> 00:16:11,610
the value for this one is going to be JWT space.

232
00:16:11,880 --> 00:16:16,740
And then what you need to do is copy this entire access token without the quotes.

233
00:16:16,740 --> 00:16:19,890
So those are copying all the way up before and after the quotes.

234
00:16:19,890 --> 00:16:25,830
Copy this and then JWT space go ahead and paste that in.

235
00:16:25,860 --> 00:16:28,320
It's kind of easy to mess this up because how big it is but there it is.

236
00:16:28,320 --> 00:16:29,900
JWT.

237
00:16:30,110 --> 00:16:35,750
So once we have that data with space and then the access token go ahead and send your get requests for

238
00:16:35,780 --> 00:16:37,000
the puppies.

239
00:16:37,310 --> 00:16:42,500
And now that you sent it you should see all the puppies available which in this case are Samie and Franki

240
00:16:42,840 --> 00:16:48,590
and now we can see that only authorize users with a username and password first need to get authorized

241
00:16:48,680 --> 00:16:52,910
and then they'll get back the token and then they can use that token to actually make the request for

242
00:16:52,910 --> 00:16:59,030
things that require that Jason web token and that's the very basics of using flask JWT.

243
00:16:59,030 --> 00:17:00,260
You can check out the documentation.

244
00:17:00,260 --> 00:17:01,930
They have tons of more examples there.

245
00:17:02,030 --> 00:17:04,820
In order to expand this to your own use cases.

246
00:17:04,820 --> 00:17:05,540
All right.

247
00:17:05,540 --> 00:17:10,810
Coming up next we're going to work through an example of how to use flask rest API with instead of in

248
00:17:10,840 --> 00:17:14,300
memory things like lists and dictionaries with actual models.

249
00:17:14,300 --> 00:17:17,320
So should be pretty simple to answer that model stage.

250
00:17:17,330 --> 00:17:22,340
And I think what you see that you'll be able to add in flask rest API to any of the projects we've done

251
00:17:22,430 --> 00:17:23,350
in this course.

252
00:17:23,600 --> 00:17:25,010
Okay we'll see at the next lecture.
