RESTful and HTTP APIs in Pyramid Transcripts
Chapter: Authenticated services
Lecture: Setting up users
Login or
purchase this course
to watch this video and the rest of the course contents.
0:01
In this chapter, we're going to add a type of authentication that is super common among APIs.
0:07
Basically what we're going to do is we're going to pass an API key along with our client to send this data over basically to show who we are
0:16
maybe this is just because we don't want to have a public API that anyone can use for free or just out in the open
0:22
we want to be able to track who's doing what; maybe the actions are actually modifying things on behalf of a user
0:28
think of github, if you say create a new repository and you pass an API key, right whose account is that going to be created in— yours, right.
0:37
So we're going to talk about those types of things in this chapter. Now, let's start right away with a demo,
0:43
so what we're going to need in order to get started is, unless we just want to have one API key for the entire thing,
0:50
which doesn't make any sense, is we're going to need users, so let's go and add another sequel alchemy type here
0:56
and I'll call this user, and we're just going to have a class called user and it's going to derive from sqlalchemy base as we've just learned, like so.
1:06
Now let's give this— let's go and explicitly set the table name first before I forget, then let' go ahead and give it an id
1:16
and we are not really going to do much with the id it's just going to be autoincrementing, so we'll have a column,
1:23
we can import that from sqlalchemy, and it's going to be an integer we can import that, and it's going to be a primary key,
1:32
and it's going to be autoincrementing true. So here's a nice simple autoincerementing id and let's also go and record when these users were created,
1:40
like whenever I have accounts and account behavior, like a little tiny bit of auditing, always good; so we'll go and create a datetime, call him here
1:51
and we'll set the default to datetime.now. Remember, don't call the function, pass the function. Ok, so now we get into interesting things,
2:01
we probably need a username or an email, often those are actually the same thing in the database, email is name, same thing.
2:07
So let's have this be a string from sqlalchemy, let's say that it's nullable, it's false so that we require it, it has to be unique,
2:17
and we want to be able to index it, we want it indexed, so we can query it, if this is the way you log in with your name
2:25
then obviously we would like to have that unique, we can't have multiple users. We're also going to have a password and it needs to be super explicit,
2:34
this will be hashed password, and we don't need any indexes, or anything that, technically it doesn't have to be unique
2:40
although you kind of hope it is, so remember never, ever, ever, store plain text passwords you always hash it, use something like passlib
2:49
working with this is really out of the scope of this project, this course, but if you are going to have a password, hash it and use passlib.
2:56
Okay, now we get to an interesting thing that we're actually after, the API key, so in here, it's conceivable that we'll have many API keys
3:04
and you can expire them and give them different privileges and whatnot, in our world, things are simple a user has a single API key, alright,
3:11
and you guys can extrapolate the data model if you want to do something more adventurous.
3:16
So here what we're going to say is the API key, it has to be a string, let's go ahead and have it automatically generated,
3:24
so when an account is created that it's just going to automatically be there
3:28
they might not know about it, but if they go and look in their little section
3:31
and their user account if we had one, it would say your API key is such and such. So let's set this to be a function that we're going to call,
3:37
an empty lambda that's going to return a string representation of uuid4 alright, so that's a decent key there, and we also probably want an index
3:50
because when our API call comes in, the thing we're going to be given is the key
3:55
and we need to get the user, so we absolutely want to have this index = true. Okay, I think that's going to be solid for our code here,
4:03
I suppose one other thing we could add although the way we're generating it it's not a problem, but this is also like an effective user name,
4:12
so let's go ahead and set this to be unique, although it's going to be kind of funky to get that generated,
4:17
there's no reasonable chance of that being duplicated, but maybe somebody copies a value from somewhere
4:23
and tries to set it somewhere else, so a little bit of protection there as well.
4:26
Now, let's look at our database, and in this one we don't have our data so we have car, and we have some management details there,
4:35
let's go and rerun this, and then refresh this. Now, notice there's no user, sadly and for whatever reason
4:48
the system is just not pulling this in, it hasn't been pulled in yet, we could start using it other places and it would probably be ok
4:55
but let's just do this, let's be really explicit here, let's just say import, so we'll just import the user here.
5:02
Now, we're not going to use it in any way, but this will before we call this function here, we'll sort of show sqlalchemy base the user class.
5:11
So if we try again, we refresh, magically there's our user, with everything we need.
5:16
Ok, so we have our user, let's go and write one quick query over in our repository, so we are going to be doing a bunch of stuff,
5:25
and down here, we'll ave a class method and let's say what we want to do is get, I'm going to call it something like that,
5:32
find user my api key, it's just going to take an API key, we could even tell them hey this is a string and it returns a user if that's what we want.
5:44
Ok, so then just like before, standard stuff, so we're going to come over here, create a session and then the session is going to be a query of user
5:52
and the filter is going to be user.api_key == api_key alright, this is why we need that index, right, so that's good and this will be a user
6:04
and let's say session.close and then just return user and because we're using first, if there's no user with that API key
6:12
like some of these are passing nothing or they are passing an incorrect one or whatever,
6:16
it's just going to return none, which is pretty decent representation of no user. Okay, now we have this in place, the next thing we have to address is
6:27
how do we pass the data from client to server.