Python for Entrepreneurs Transcripts
Chapter: User accounts and identity
Lecture: Demo: Getting started with logging in
0:04 Back in PyCharm, let's add this ability to track logins and know what the logged in user is to our web application.
0:13 The part where we actually do the log in is in the account controller on these two methods, the signin_get and in particular the signin_post.
0:22 Now, we are going to do a lot of code, juggling some cookies and things like that,
0:26 so let's take that code and put it somewhere else, over in this infrastructure bit, I am going to create a file, Python file called cookie_auth,
0:36 and here we are going to use a couple of methods, right, so we are going to define a method called set_auth and for set_auth
0:43 we are going to need two things, we are going to need the request this is the request that comes into the web action method
0:51 and we are going to want to store the user id, OK, now remember, if we look really quickly at our data, where is our user, our account,
0:58 our id is actually a sting which is a fairly large I think 32 character alphanumeric string. So that is what is coming in here for our user id here.
1:10 now what we ultimately want to do is we want to go to the requests, and say set_cookie, now it's going to turn out this is not going to work
1:18 as well as we're hoping but this is the plan, we're going to do it the wrong way and then I'll show you a way that works a little better.
1:25 So, next, the question is what do we put into the cookie? We could put anything we want in terms of a string,
1:31 I think there is limits but reasonably storing the user id is no problem,
1:35 however, one thing that is a little concerning is if I just put the user id in there,
1:39 what if someone forges a cookie and then just starts guessing user ids, because our user id is a 32 character alphanumeric string that alone
1:49 is going to be a super super hard, what we can also put a little verification on here
1:53 to make sure that you can't just stuff user ids in here but to verify that the user id
1:57 comes from our web app, we'll add an additional secret that we can test when we get the cookie back.
2:03 So what are we going to have, it's going to look something like this, we are going to have the user id, let's just say, I said alphanumeric, didn't I,
2:09 let's say it looks like this and then we are going to in here have some kind of hash of the user id, so then when we get it back
2:17 we can look at this number and then we can look at this, and make sure "hey, this was the hash we expected to generate
2:24 given that user id" and that will make it much harder for people to guess. So let's begin by coming over here and get the hash, hash_val,
2:32 now in order to do this, we are going to use a simple library called the hashlib,
2:36 OK, so up here, we are going to import hashlib, we want to take our hashlib, and we are going to sha512 algorithm and we are going to hash this user id
2:47 but you can't give it a string, you have to give it bytes, so we can say go over here and code that string, in the bytes, using utf8.
2:54 And what we get back is a hash object, and we don't want a hash object, we want a string, so we can say give me the hexdigest of that,
3:02 and let's just print out the hash value here just so you can see what is coming on, and comment this out.
3:10 So let's just run this to make sure everything is coming out good, it turns out we are going to hash something else in just a moment.
3:16 So let's come over here and we'll say first we import a cookie_auth alright,
3:24 so I want to come down here we are just going to call cookie_auth.set_auth on account.id, OK, so here we sign in, we get the authenticated account,
3:34 either we get nothing and we tell them an error or we get the actual account back then we'll have access to its id
3:38 and we should see what is going to happen here. So, let's go sign in, I'll just use my saved credentials, this is from the last video,
3:47 I just remembered them, we are not passing the user id apparently. Oh, we are but we are not passing, what we really need to pass is the request,
3:56 we didn't technically use that so I forgot about it, but we are going to use it in just a minute, let's try again.
4:04 Alright, so here you can see this is this huge hexdigest, alright, but this should be fine for what we're doing,
4:12 it's huge but a 120 characters, not that huge. Alright so what we want to do is we want to create the value
4:18 and we'll say the value is going to be the user_id: the hash. Here we'll just say user_id, hash_value.
4:27 alright, so our goal is going to be to take this and actually set the cookie.
4:32 So setting the cookie is really easy but it turns out there is going to be a little catch that we need to be aware of,
4:38 so I want to make sure you run into it so you understand this sort of slightly more complicated version that we're going to have to go through.
4:44 So I'll call this auth_cookie_name, and let's just call this blue_yellow_auth, or user something like that.
4:56 So we're going to have to ask the browser for this cookie, and then we're going to tell it to save it, so what we do is here we say the cookie name,
5:04 we say the value and then we say the timeout. So let's say we'd like to save this log in cookie,
5:16 for either 30 days in which it will expire or until they log out and we'll talk about logging the out in just a minute.
5:24 Now you would think, you would think that this is going to work. However, let's find out. So I rerun this, I go over here and refresh
5:33 and if we go and actually look in the network tools, let's do one more request there we go, and only see HTML, OK, great.
5:45 So if we look at this and we look at the cookies, you can see that PyCharm has inserted some kind of cookie for us
5:51 because it wants to be able to debug this request, right, this is basically running in the PyCharm web server right now,
5:58 but the cookie that we added, it's not there. So that's weird, and it turns out this is just some bizzare thing, with Pyramid,
6:07 somehow the combination of all the pieces we're using kind of dropped the cookie along the way.
6:14 Oh, actually one mistake I did make, this is supposed to be response cookie,
6:19 obviously, so let me just verify one more time that it's still not setting the cookies.
6:24 so we click on it, still not setting the cookies, so request we get the response,
6:28 we tell the browser "set this cookie", it didn't set it so this turns out to not work,
6:33 as well as we're hoping and the way to make it work is we have to hook into a different point in the life cycle of Pyramid.
6:40 I feel like this is a bug, at least in extreme shortcoming, I don't really know why this is happening but it's easy enough to solve
6:47 so let me show you how we are going to do this, we are going to have a function here,
6:53 and I am going to hide it from people importing this module that we created here so use a double underscore,
7:01 so we are going to have add cookie callback and in here, I can do this code basically, adjusted for what I changed names here
7:09 so this is going to be value, this is going to be plain name and this will be the request and let's go ahead
7:15 and also do this way I think we can just do it response.set cookie. So how does this get called, right, if we don't do it up there?
7:23 Well, what we're going to do is we are going to tell the request: "hey, when you are just about done, call this function for us."
7:29 Let's put nothing there. So we are going to say add response callback
7:35 and this thing takes two values, directly, so it takes the request and the response but I also want to pass the name of the value
7:43 so I can create a function that is a closure that we could pass those along, so I'll create a lambda,
7:49 of request response and in here I am just going to call this function,
7:53 and I am going to call it with of course the request, the response, that's passed through
7:59 in the lower levels of Pyramid and then I am just going to give the cookie name which will be the auth_cookie_name and I am going to give it the val.
8:07 OK, so instead of trying to set it directly, we are just going to say "hey, do a callback, set it here", let's try again.
8:13 Reload the page, and now we're going to need to set the cookies, so let's go to our sign in, now if we look at our GET, check it out,
8:24 our blue_yellow_user is here and then there is the log in. So you can see setting cookies is super easy, there is this weird catch
8:32 where you've got to do it through a callback but really it's not hard at all to set.
8:36 So this cookie will be around for 30 days and then we can ask for it, so the next thing we're going to do is we are going to go and actually
8:42 read this cookie and make it accessible to the rest of our web application.