So now that we've introduced CSRF conceptually, let's talk about how we actually implement it running in Django. So if you remember, I didn't really point this out too much when we went through it. This was my first form where I showed you how data could be transported to the server using a POST request. If you look at the top, I have this little annotation @csrf_exempt and there's a little import above it in our views file, and what I was basically telling Django is don't blow this up because I'm not handling CSRF properly. So what we're going to do is we're going to do the exact same view, except we're just not going to have that little thing. So we'll call this one failform and we're going to throw out a form, we're going to press submit. Everything looks fine, the only difference is I did not turn off CSRF processing. So on a POST request, CSRF processing is on by default, which means that we have to do something explicitly when we're hand-making POST forms, but I didn't do it yet. So this is what happens if you don't do it. So you get a form and you type some stuff in and you hit Submit Query and boom, you get this Forbidden message, that's a 403. So among all the HTTP responses, we've got 200, which is okay, we've got 302, which is moved, and we've got 404, which is not found. 403 is you're not getting this page, but not because I don't have it, but because you're not authorized to do it. So this is aborting and stopping the POST. So it comes in, you look up the session and everything looked good except the CSRF did not match. Now, we are a legit server, so what we've got to do is we've got to actually add the CSRF to the POST on the way out, okay? So this is the exact same POST, and I'm doing this kind of at a low level, and I'll show you a much easier way to do it in a minute. So we have an input hidden. I just happen to know that csrfmiddlewaretoken is the proper name for it, and I'm just going to have a placeholder, which is __token__. And so then what I'm going to do is I'm going to talk to that middlewarecrsf get_token. Now, that token is probably just a number sitting in the session, but I don't need to know that. I just say, "Hey, give me the token for the current request." The request is, of course, all that data that's coming in, it's got the session, it's got everything else in it. So, "Hey, give me that token." This is a big long string, which is really just a big long random number, a big long random string. And then what I'm going to do is take whatever that big long random number is, and I'm going to replace this little bit with a a simple replace, and then I'm going to send that out. So this time when we go to that page, you'll see that now we have an input type equals hidden, name equals crsfmiddlewaretoken, and then the big long middlewaretoken, whatever that is. And then now when we submit it, it bundles up both the guess and the middlewaretoken, and it actually bundles up the submit as well if it's got a name, and sends that in as POST data. So now when it dumps out, you see, oh, well you've got guess equals 42 and csrfmiddleware. Now, by the time it's got to this point, we're not really doing the checking here. The checking was done before the view started. And so if we go back to the view here, the checking is done before it gets to here, when you're dispatching from urls.py to this and it says, "You didn't tell me not to do CSRF and it's not done properly, so I'm going to blow you up." So if it's going to work, it's already worked. The fact that we've come in here and we're dumping this stuff out of the POST, that's just sort of like we see it, but it would have blown up before it would have even got to our code at that point. But we do get it and see it as POST data. We don't need to because if by the very fact that our view is running means that the CSRF processing has been successful, okay? And again, the rogue system has to somehow get its hands on this, the actual number of the CSRF, and that changes every time you log in. And literally it could change every hour or so or whatever, and so it's a hard number to guess and it's a hard number to get your hands on. Now, that manual thing is not the easiest way to put this in, there's an easy way in CSRF. You simply say, So here's our form, here's our slash form. I do all the stuff I want to do and then I use the code, it's called a template tag. When you have CSRF enabled in your Python, you have a template tag of csrf_token, and that emits the input, the type equals hidden, the right name, and all that stuff. So you as the developer using templates, you don't have to know anything about that, okay? And so that's how we do CSRF. And the only other thing we've got is a guessing game and then we're going to pass a message into that and we're going to do that in a bit. We're going to use this for a whole bunch of little examples. So kind of remember this particular guess.html template, but the key right now that we're talking about is the fact that we've got this CSRF token in. Now, I'm going to write a bunch of guessing games, and in these guessing games I'm actually going to start checking the guesses. So I'm going to have a function in this view that's called checkguess. And it's pretty simple, it returns a string or false. If the guess is an actual non-false thing, we check to see if it's too low, too high, or right on time, Or if it doesn't convert, if this int guess throws a traceback, well, then we'll say bad format for guess and then just because it probably came from the user, we're going to escape it and then send that back. So whatever it does, we're going to send back a nice little message going back. And so here is a simple guessing game that we're going to do, and so we're using a class-based view this time. Of course, we extend the class View, and remember how it works this is it's not just a function, we actually have two methods. One is a GET request, and the get is called when we're receiving a GET request, and the post is called when we're receiving a POST request. This alone is one of the nice reasons to do this. You don't actually have to say, if it's a GET, do one thing, if it's a POST, do another thing. We just have two methods and Django properly routes the requests in, okay? And so this is going to be a form POST. So on the get, we just render with no messages, there is, and we have a CSRF token that goes out, so we just render it. Then we'll click the button so that this render right here will produce this page. Then we type in the guess of 42 and we hit Submit Query, and then that bundles it all, up including CSRF, and goes to the POST. Now the CSRF, as long as we put it in that template, we don't care because before that post method gets activated, CSRF has been processed and we get a 403 if the CSRF isn't right. So if we go back up here and we don't put this in and you run this code, the csrf_token, you don't put it in, then when you hit this, it's never going to make it to the POST, it blows up in route to the POST if the CSRF doesn't happen. But we've got CSRF and it's all automatic, we just throw that one line inside of our form and that's all we've got to do. So we put 42 in, we hit Submit Query, it passes CSRF, it comes in. So we grab the guess from the POST data. We call my little check message, checkguess, that's going to give me that little message whether it's too low, too high, or some kind of other mistake. And then I'm going to pass in a context, the string message has that string, and if then we go, I have it down here, no. I have it up here. So then the message comes out. So this, you'll notice I've surrounded this by an if, so that if the message is false or not present, then it doesn't put anything out. But if it is, it actually puts the message out. And so out comes the guess, and so this is what it looks like when we do a GET request, right? We see this, then we're going to see all this stuff, we're going to type our number in, we're going to hit Submit Query, and then it's going to fire up a POST request. So then it's going to come back into the POST request, It's going to get the guess from the POST data. It's going to check it, and then it's going to pass the message in. And so the message is going to come out here, and then we're going to return that page. And so you're going to see something like Congratulations 42. So that took, that was part of the POST, and so we now have made a successful guessing game. So next we're going to talk about, just when we get something working, there's always something that we have to say, oh, but there's a little detail that we forgot about. So up next, we'll talk about POST and Refresh, which is a little problem that we're just going to have to fix. [MUSIC]