Welcome back, everyone, to this lecture where we're going to apply user authentication protocols onto
views.
There's two ways of doing this.
There's decorators for function based views and then Nixons for class based views.
Let's explore both of them.
All right, here I am, back at our library project.
The first thing I want to explore here is actually displaying something to the user, letting them know,
Hey, you're actually logged in.
We already know that Django's authentication system actually passes a user object that we can access
inside the template.
So what I'm going to do here is simply go to the index page.
Remember, it's very simple.
It just says home page, the total books and then the number available.
What I want to do is actually have an if statement that says, Hey, if the user's authenticated, say
you're logged in.
So what I'm going to do here is add in an if statement that says if.
And then we say user dot is underscore authenticated just as we've done previously.
And then we'll say if the users authenticated.
I'll have a paragraph here that says you are logged in.
And later on we can actually access attributes that are built in to the user, such as the username.
They can check out the documentation for a list of all the attributes.
But for example, I could say P and then insert the user dot and then we can say get user name.
And then close that off.
And I can say something like Welcome and then their username.
So let's actually save this and let's check out and let's actually say else real quick here that we
can say else if they're not logged, then we'll say you are not logged in.
To see these changes.
You may want to restart running this summer.
Control see here and let's run that server and make sure you visit the server inside an incognito window.
Sometimes, depending on your browser, it may start actually caching in information which is not super
ideal because we're still playing around and changing the website a lot.
We don't want it to accidentally cache that you're logged into the website.
So we're going to do here is go back to your homepage and you should see now it say something like you
are not logged in or remember to visit this incognito and also to restart the server.
So I'm at my home page.
I see the total books number available and it says I'm not logged in.
Remember that we have the default account URLs that come with Django's user authentication system,
which means based off the templates that we created earlier.
So if you come back here, you can check with the templates.
Remember we have under registration logged in that HTML.
So let's explore that one real quick.
So we're going to go to accounts.
So we'll go to accounts.
Forward slash.
Log in, hit enter.
And you're going to have a kind of disgusting form here because I haven't really stylized it, but we
already know I can add a bootstrap in and other things that make this look a lot nicer.
So let's put in the username and password for the user we created earlier.
Remember we created this user in the admin and right now I'm going to say my user and the password I
selected was simple.
It was my password.
One, two, three.
I remember we also reconfigured the redirect that should go back to the homepage after logging in.
So I'm very zoomed in here.
You'll see something like this.
So just keep that in mind.
Log in.
And an out says you are logged in.
Welcome my user.
Okay.
So what have we proven so far?
We've proven that we have the capability to create login pages based off the URL.
We're able to actually log someone in and then we can detect whether or not they're locked in with just
those features.
You now have very powerful tools available.
Because if you go back to the templates.
So if we come back here to our index page, the fact that I can check if a user is authenticated.
That means later on I'll be able to check the user's particular ID and then make calls to my models
and start collecting things based off their I.D..
That's how we can start to begin to build things like a profile page.
So so far, we have actually restricted anything based on somebody being logged in and authenticated.
We're just showing them different information if they're logged in versus not locked in.
So what I want to move towards now is actually authentication based restriction of pages.
That is to say, you're not even allowed to see the content of the page if you're not logged in.
Anybody can still see our homepage.
It just displays differently if they're logged in or not.
But what if I want a particular page to not even show up and just tell the person, Hey, you have to
be logged in to see this page?
It's actually restricted based off who you are and whether or not you're authenticated.
Let's explore how we can do that.
To begin.
What I want to do is in the same way, create a log in HTML.
I'm going to create a very simple log out page.
That way the user has the ability to log in or log out.
In fact, right now, if you were to go to forward accounts, forward slash lockout, you would actually
see your user being logged out but taken to the Admin Logout page, that's not exactly what you want.
In fact, it'd be more convenient if we could say, Hey, our own little page here, you've been locked
out.
That also means that we need some sort of button to activate being logged out.
So let's check it out.
I'm going to underneath registration, create a new template.
So I'll send you a file.
And this one under registration again is going to be called logged.
Underscore out the HTML.
And remember, these are kind of special, reserved template names.
So you have to follow along with me here.
So this is the page that actually shows up when someone has logged out.
So keep in mind, they're already logged out by the time they click and get to this page.
Essentially, that is to say there's going to be buttons on other pages that have the word.
Click here to log out and then it redirects in this HTML page called Log Out that HTML that essentially
informs Django, Hey, if this person has visited this page, use your administrative capabilities to
log out this person.
So that means on this page, if we begin to type out the doc, we really just need the information to
say something like, you have been.
Locked up.
And then if we want to, we can also add in information to log back in.
So we could, if we wanted to make a little button here that says, hey, click here to log in again
so I can create an anchor tag that uses my URL routing.
So let's try this.
And then here I'm going to say.
Your URL tag.
And we'll have it for the login tag here.
And then inside we're going to say click.
Two.
Well, let's just say click here.
To log in.
Remember this is a page to get visitor to post being logged out.
So the one last thing I need to add is some button somewhere that actually tells them to log out.
Well, the home page is probably a good example of that because remember, I'm only checking if the
user's authenticated.
I do not want to show a log out button if the user hasn't logged in yet.
So be careful when you're designing your pages and templates that you're not always displaying a log
out button or a login button that should actually be conditionally chosen based off if the user is authenticated
or not.
Which means here I'm saying if the user is authenticated, they're logged in.
Welcome user and I should give them the option to log out.
Lots different ways I can do this.
One simple way just with a reference to go to the log out h html site.
So here I'm going to put an anchor tag and the reference is going to be to a URL.
And then it's going to be log out.
So we'll say log out here.
And then I'm going to set this up.
Now, the question is, I should be using some sort of request path in order to have them go to another
page after they're able to log out.
Essentially, there's a next parameter that we can use.
So I can append a special next parameter to the end of this year URL.
What this does is it's going to add a URL parameter called next that contains the address URL of the
current page to the end of the linked URL.
Essentially what that means is after the user has successfully either logged in or logged out, the
views can then use that next value to begin to redirect the user back to the page where they actually
first clicked that log in, log out link.
It's technically optional to use something like this, but it's going to make the flow of your website
make a lot more sense.
So let's try it out.
The notation for this is to say the following question mark here.
Notice this all going inside the quotes.
Then we're going to say next.
Equal to and then we'll say request.
That path.
So notice there's essentially the request object that's being passed back with all the views that we
always see.
You can actually grab that path and then I'm using a little bit of your encoding here to say next is
equal to that request path.
And similarly, if you're not logged in, I should probably have a link to the login page.
So let's put that in as well.
We're going to create an anchor tag here.
And in fact, it's going to look extremely similar to this.
So let's just copy and paste the work we've already done here.
And just switch it with a log in.
And then we can save that.
All right.
So I have indexed each HTML and it's checking whether or not someone is logged in and or logged out.
And then we can actually say, if you're logged in, you can log out.
If you're not logged in, then you can log in.
Okay.
So always be careful on making sure this logic is correct.
You don't want to show someone a log out button when they're still locked out.
So just be careful.
If that sort of users authenticated their logged in, that means they should be able to log out.
Otherwise, if they're not authenticated, they should be able to log in.
So I'm going to save those changes.
Let's go ahead and let's actually restart this server.
Now, remember to be visiting this incognito mode.
We don't actually have any caching issues here.
And I'm going to refresh the page and you'll notice I'm refreshing here.
And I see you are logged in.
Welcome, my user.
And we actually don't have any text here in the anchor type.
I forgot to fill that in.
So let's click this to log out here.
And then this is going to say, log in here.
Okay.
Now I'm going to refresh.
There we go.
Now I see logout here.
If I click this, you'll notice it's going to say Account's log out, so click here and I'm no longer
logged in, so it goes back and redirects me.
So essentially what that did is it's able to, if I come back here, come to logged out h HTML and then
immediately redirect them to next, which is going to say, hey, go back to the current page that were
on.
Let me show you what happens if I actually delete that so you can get an idea of what it's actually
doing.
So I'm going to hit.
That.
Let's save it.
I'm going to.
Refresh this and log in again.
I'm currently not logged in.
Going to log in here.
My user.
My password.
One, two, three.
I click log in and now I'm logged in my user.
Remember when I clicked logged out here because I had that next capability, it essentially very quickly
skipped going from logged out the HTML two back to the home page.
But if you actually wanted something to specifically tell the user, hey, you're logged out, I'm not
redirecting you anywhere, then you can click log out here and it says you've been locked out and you
can click back here to log in.
So let me explain what's going on here again in terms of the template.
So that is the behavior without this next requirement.
So essentially what next does is it says, hey, the page you are currently on that is this request
that came into this template has a path which in this case is indexed to each HTML our homepage if you
want, I can reattach that here to you.
The URL that says, hey, once they're logged out, take me back to the homepage.
This is going to depend on the behavior you want on your website.
Do you actually want your website to have a specific page that tells a user, Hey, you've been logged
out?
Or would you rather just redirect them to the homepage telling them, By the way, you're no longer
logged in?
It's up to you whether or not the logged out page is important to you to show.
But now let me show you behavior one more time with this next request path added in here.
So remember, I'm currently logged out.
Going to click here to log in.
And when, say, my user.
My password.
One, two, three.
I hit log in and I'm currently logged in.
Welcome my user.
Last time I clicked log out here.
If I didn't have that next, it actually took me to logged out that each HTML.
But now if the next it's going to redirect me automatically.
And take me back to the homepage.
So that's the sort of behavior that you get to decide what to choose and what to show.
What we're going to do now is, as I mentioned, expand on this and show you how to use user authentication
within views.
So we've done a lot of work with templates, but what about views?
I want to actually block somebody from even viewing something.
And that depends if you have a view that is function based versus class based.
So let's go to our views.
So here I am a views up high.
Remember, we have our index page here and we also have the ability to create a new book as well as
detail a book.
I'm going to create a very simple view.
It's going to be called my view takes in a request.
And then this is what this is going to do is simply return.
Um, actually this just render a new template.
So I'm going to render a template that's, let's say, special and it says, hey, welcome to the page.
Only logged in users can see this.
So I'm going to say request here and I'm going to say catalog forward slash, let's say special.
Actually just call it the same as my view.
The h html.
And if I want, I can pass any context.
But there's no context that exists here.
So go ahead and say this view.
Again, it's a function based view.
My view render a request.
Catalog my view.
HTML.
Main idea here is I only want authenticated users to be able to see this, so I still need to make that
template.
We'll send you file here.
Going to call it.
My view that each Tamil so far, what we understand is I can grab the user and say, okay, if the users
authenticated, show them something on this HTML.
That's actually not exactly what I want to hear or do here.
What I want to do is actually restrict access to this view entirely and say, Hey, sorry, you're not
going to have access to even see something from this HTML if you're not logged in.
So I'm just going to create a very simple heading that says Logged in users only.
And save that.
And let's go to our Urals up high and let's add in that view.
So I'm going to say path.
Here.
And it's going to be called my view.
So this is forward slash my view and this is from views that my view and we can give it a name of.
My view.
Then go ahead and save that.
And if you want you can link this formally.
But we'll just go to catalog forward slash my view to see what actually happens here.
Now, remember, we haven't actually done any restrictions.
We haven't done any restrictions on template side of things and I haven't done any restrictions on the
view side of things.
I just created a very simple function based view.
So if I go to that page right now on my home page, notice I'm not logged in and if I go to forward
slash catalog.
My view and enter this is logged in users only.
Obviously I don't want that behavior because I'm currently not logged in.
So how can we add a simple decorator call that requires a log in to see that page?
Well, it's super easy of Django.
You scroll up to the top and for function based views, you're going to go from Django dot contrib.
Dot off dot decorators.
You're going to import the super simple decorator called login required and this allows you to just
decorate a function to require login to see that page.
So we scroll down here and then I simply decorate that function with at log in required.
Go ahead and save that change.
And that's the very simple code.
I'm just decorating it with this.
And so come back to my home page here.
Refresh this.
I'm currently not logged in.
Let's see what happens if I go to catalog forward, slash my view.
It says, please log in to see this page.
Notice that was automatic.
In fact, I didn't even have to write this.
It essentially just takes you back to the log in page.
So now the user doesn't even get the chance to see anything.
If the users are authenticated, show them this piece of template, etc. This is no longer happening
at a template level, which means this is essentially higher security because it's not actually giving
them the chance to maybe view the source code and try to decipher what's being shown to them and what's
not.
It's basically a redirect to the log in a page to see that.
So the other way to do this, again, this was for a function based view.
The other way to do this for a class based view would be something like a Mixon.
So let's show you how to do that.
Remember, right now I have the book creation form, which is available to anybody that can log in and
just create a new book.
So if you go to URLs up, I remember I can just go to forward slash create book and anybody can do that.
So let's actually try it out right now.
So if I go, let's say back to my home page.
So let's go back to my home page here.
So I have the home page.
Now I'm going to go to catalog forward slash, create book.
And as we mentioned a few times, this is probably the sort of page where you don't want anybody to
just be able to visit, create new book.
They should actually be logged in.
And then later on, we can say not only do they need to be logged in, but the user needs to be part
of the group that is equal to librarian.
Remember, we can actually now create groups of users and that way I can start filtering.
Hey, if the user is authenticated and the user group is equal to librarian, then they can access this
page and start filling out the form.
So let's say I actually want to block this.
Well, I can come back to the user pie and book create is a great view.
Remember previously I used a decorator and a decorators view to make sure it was logged and restricted.
But as I mentioned, for class based views, it's a mix.
So we say from Django, the contrib, the off dot.
Nixon's import.
And this one is the log in required Nixon.
It's super simple to use.
You just come back down here and you essentially pass it into the view.
You mix it in, so to speak.
That's where the name comes from.
So we'll say required mix.
Then make sure you spell that right.
But now it's required that you're logged in to see.
But correct.
So going save that change.
Let's go back to our homepage.
So here I am back at the homepage.
I'm currently not logged in.
If I try to go to forward slash now create book.
Then I have to say log in to see this page.
Let's actually log in now and see what happens.
Say my user.
My password.
One, two, three.
It log in and now I'm forwarded redirected back to the page that it was initially trying to see.
And that's that next protocol.
That's typically the behavior you want in your website.
You want someone who, if they're being blocked and having to log in that once they log in, they get
redirected back to the page they initially wanted to view.
It doesn't really make sense to redirect the user back to the home page after you type in or find create
new book again.
All right.
So what are we covered so far in this lecture?
Well, we covered the two main ways of requiring user authentication to actually visit a view.
One is decorator based or function based views, and one is mix them based for class based views.
Super easy.
You just do these two imports here and then you can begin to play around and add those into your views.
The other thing we discovered is the ability to log in and log out as well as use your template and
your Django template language to create views and templates that appear different depending if you're
logged in or logged out.
So keep those two ideas separate in your mind.
There's the ability on the template side of things to display different information, whether the user
is logged in or logged out.
But then there's also the view side capability to actually require logins to even visit a page.
And if they're not logged then we can redirect them to the login page.
In order to log someone out you should have this logged out each HTML.
And then again, as we mentioned, it's up to you if you want to redirect them to the next page or if
you just want them to stay on logged out.
H html.
Okay.
That's it for this lecture.
I'll see you at the next one.