Understanding Django authentication by Renato Oliveira

This video features Renato Oliveira at DjangoCon US 2019 in San Diego, California, USA.

Understanding Django authentication by Renato Oliveira
0:25:14
Published October 25, 2019
2,083 views

DjangoCon 2019 - Understanding Django authentication by Renato Oliveira

Django gives us a built-in authentication system. It's an awesome asset for doing web development strictly with Django, but when you try to do something else, you’ll need to integrate with other options. Understanding it at a base level makes more advanced authentication systems easier to implement.

This talk was presented at: https://2019.djangocon.us/talks/understanding-django-authentication/

LINKS:
Follow Renato Oliveira 👇
On Twitter: https://twitter.com/_renatooliveira
Official homepage: http://www.labcodes.com.br

Follow DjangCon US 👇
https://twitter.com/djangocon

Follow DEFNA 👇
https://twitter.com/defnado
https://www.defna.org/

Intro music: "This Is How We Quirk It" by Avocado Junkie.
Video production by Confreaks TV.
Captions by White Coat Captioning.

Summary

Authentication establishes that an identity is genuine, using knowledge, possession, or biometric factors; sensitive systems may combine multiple factors. Django’s built-in system uses middleware, sessions, and authentication backends: `authenticate()` tries configured backends, while `login()` stores the authenticated user and backend in the session and `logout()` flushes it. The speaker traces request processing for anonymous users, session changes, login, and logout, including session-store behavior, expiry, cookies, and session-key rotation to preserve pre-login data safely.

Key takeaways

  • Authentication can rely on knowledge, possession, or biometric factors, and critical systems may require more than one category.
  • Django’s `authenticate()` iterates through configured authentication backends and returns a user when credentials are accepted.
  • The default model backend checks a username and password while mitigating username-enumeration timing differences.
  • `login()` persists the user ID and backend in the session, rotates the session key, and preserves existing session data.
  • Session middleware loads and saves session data through a configurable store, with database storage as Django’s default.
  • `logout()` flushes the session, deletes its key, and changes the request user back to an anonymous user.

Summarised automatically from the transcript.

Transcript

3,629 words · auto-generated Show

Automatically transcribed, so expect mistakes in names and technical terms.

0:15

So hi everybody, how are you today? Uh it's an incre incredible honor to be here and to give my first talk at Django Kong. Uh and like my co-worker Nicole used to say, I might look nervous, but don't worry, it's just because I am. Okay. Uh so let's say you want to buy a piece of art. I never bought famous art, but I suppose you should go to an art dealer, okay? So you talk to your person and they show you a painting from a famous artist. And it's really expensive. And you don't want to put so much money in something that you're not sure it's true or not. So you start making questions. Who owns it? Who made it? And how can you prove? And then

1:00

your art dealer starts showing you documents that proves the paint improvements. So it was bought from somebody a couple years ago. Before that, it was exposed in this famous museum. It was found at some point, because it was declared lost many years ago, because the painter sold to somebody that didn't care that much about art. And then voila, here's the actual Instagram post by Salvador Dali bragging about the persistence of memory So what we just did, or kind of, was to get the provenance of a piece of art. This is the chronology of the ownership of a historical object.

1:48

And it takes into account many different attributes to prove the provenance, the authenticity of a piece of art. Things like uh who was the war the artist? when and where it was the painting was made, uh how it was made and where it was accepted. And so authentication is not something only related to digital. In fact There are different types of authentication and we can get sorry, we can take a look on them next. So in this talk, we'll cover authentication types and factors. The authenticate function, authentication backends, login, logout, and sessions. But first, my name is Renato Oliveira, and I'm from the city here, Recife, probably the not the first one that you saw here

2:36

It's an always sunny city in Brazilia northeast and you should go there if you wanna like take vacations And I'm a co-founder at Lab Codes, and my day job is basically to complain that I'm not coding as much as I would like. And I've organized a few conferences in Brazil, uh, from local meetups to even Brazilian PyCon. And I know how hard it is to put together a conference like this. So I would like to thank the organizing team for that And I'm a proud member of the Python user group from my state, and I've been working with Django for almost a decade. Uh a little about lab codes, we're a software studio based in Brazil and we specialize in creating custom web products fitted for specific needs. We believe that software should be built by fulfilling clients and user

3:24

expectations, and our software is always aimed at solving problems and optimizing process. It's an honor for me and for the team to be here speaking and sponsoring. And I'll be here throughout the sprints and I'm more than happy to talk about what we do. And like I said before, I worked with Django for almost a decade and I've created my share of authentication system. single sign-ons, custom authentication. I've integrated with many third-party apps through Alpha of Two and others. And every time I every time I need to do something different, I need to research all over again So authent sorry authentication is not something like storing a record in the database, uh using a template tag, or creating an API endpoint.

4:11

It's uh you we usually do that once per project And if you work for the same company in the same project since you've learned how to Django, the chances that you've implemented it once or never are high. So hopefully this talk will help us to remember it in the future. And a little disclaimer here, uh I've I'll show some code because it's a deep deep dive talk, but I've cut some things up some some things off to try to be more direct to the point. So, authentication is the process or actions action of providing or showing something to be true, genuine, or valid. And like we just saw, it's not something only related to computers.

4:56

In fact, there are three types of authentication. The first type is accepting the proof of identity by a credible entity It can be a witness, a reliable friend, or our certificate authority. Here the authentication is implied So for example, a product being sold by a non-vendor implies authenticity, but even though they are not aware of all steps of the supply chain. The second one is comparing uh the object attributes with known attributes from that origin. Kind of the duck typing of uh authentication. And like an art expert might look at painting style, location, and form of the signature. Also builds authentication is done by comparing attributes.

5:44

The third type relies on external affirmations or documentation, like a password stored in the database, or even my passport. Some products like medicines they need to take all three types of authentication to prevent counterfeit. So uh when talking about electronic authentication, we can use different factors to establish uh digital identity. And there are three categories of authentication factors, and they are generally broken down as so knowledge factors is something that the user knows like a username or password. Possession factors is something that the user owns, like a smart card or security token or a mobile device. And inherence or biometric factors, it's something that the user is, like a fingerprint, a voice, or iris

6:31

iris pattern. Single factor authentication is based in only one category. The most common single factor authentication method we have is the combination of username and password. It's something that the user the user knows But for more critical systems with containing sensitive data, it's important to add additional factors to establish uh the security. So multiple sorry multiple factor authentication involves two or more independent credentials for more security transactions. Okay, single factor authentication, uh username, password is the most common type of authentication we have out there, and we are at a Django conference, so let's see how Django

7:17

does that. Uh Django comes by default with an authentication system. The configuration required is already there when uh on our settings. py uh generated by the start project. We need three apps of content types and sessions, and two midwares, session midware and authentication midware. The content types is used to allow permissions to be binded, uh to be associated with any model you create. Uh in the offense sessions contain the core of the authentication session framework. The main functionality of any authentication system is to let the user in. is to uh verify the user identity. So that's our entry point, the authentication function.

8:04

What this function does is to iterate over a list of authentication backends Tries to authenticate the user with the credentials provided and if uh if any of the back end says that this user is denied it stops attempting but if this the user is authenticated it will return the user This function this function is the core of the authentication system in Django, but we ended up adding another concept here, the authentication backends. This is the API provided by Django to enable multiple sources of authentication. Maybe your company is trying to create a single sign-on or you're trying to authenticate into another system with off two. The API is the same. You have to create an authentication backend, define

8:51

authenticate and get user methods, a few other stuff, register on your settings, and let Django do the rest. By default, Django comes with an authentication backend, actually two, but it usees one. Uh by default, it's the model backend. Uh uh which is the implementation of the default single factor authentication in Django. Uh so it gets the username and password. Uh gets the user and check their password. And also if the user cannothenti. Uh there's a hack here, a nice one. So the time of the response of trying to authenticate into a existent user was different than a non-existent one, because the check password uh hashes the password and takes some time to do that.

9:41

So it was easier to attackers to discover which users are actually in the database. So this um set password on the user model was added to add some response time. So we just verified our user identity using a single factor authentication. But we need to remember that we're over HTTP, which is stateless. So it doesn't carry information between requests. Uh so we need a way to know that the user already proved their identity and we don't need to ask again on every request. This is where login in sessions enter Just a moment. So logging is the process to gain access to a system by identifying and authenticating.

10:30

We already did that with the user, so we need a way to s to to know that the user already is already authenticated, uh, and we don't need to ask over and over again. Uh so the login function it takes the authenticated user and persists it into the request. It also uses the session framework to store the user primary key And can be accessed on every request using the session key. So after the login is executed, the user can access the login required resources without needing to provide their credentials again. Uh logout basically undoes login job. It flushes the user session and changes back the user uh in the request to an anonymous user.

11:20

Like we can see on the scope. And like I said before, HTTP is stateless, which means that the message between client and server are completely independent from each other. There is no sequence or behavior between requests. So if you want to keep track of your user actions, you need another way another way to manage that. Session is a temporary and interactive information interchange between two or more communicating devices, or a computer and a user. It's a mechanism that lets you store arbitrary data per browser and have that data available whenever the browser connects again So we could store all that data in cookies or URL parameters.

12:06

In fact, they are very handy in some cases. Uh let's imagine a hotel aggregator service. To find a place you need to put the seat you want to go, check-in and checkout dates, number of rooms, people traveling with you, and the and if you're traveling for work And then you found the right room and you need to share the information with someone else. Or maybe you want to save to look at it later. A good way to do that is to have all that information in the URL. It's insanely ugly, I know, but it's very useful. That prevents us to create an account or login to the system just to save the search and also allows us to share the URL with someone else and whoever gets it

12:52

will see the same information. But for sensitive data, uh the best way is to store on the server side. So, there are many ways to store browser data in Django. Uh, it can be a database, a file, a cache. And you can either use Django to store in your cookies, but encrypted. But Django's default implementation uses database. Actually we have all the implementations in Django, but it comes by default installed with database. So the session model has three attributes: uh the session key, session data, and the expire date. And it lives inside the session app. When you migrate migrate for the first time, the table is created, but if for the each time our session was updated, we hit the database,

13:43

it wouldn't be very performatic. For that, Django has a session store object. There is an interface to access our session data without all the model database overhead. And it only saves once per request request. The session store is a subclass of the session base Uh and there is an implementation for each session-based option Django provides to us, and it exposes some methods to handle the session data. Create, delete, load, and save, which actually saves the data in the database. It's also a dict-like object, so you can deal with all the data using dictionary operations.

14:31

You can use the session by instantiating the session store object directly using the session key you already have it if you already have it, or not passing anything if you create a new one. But when you create uh when you call create, uh it will create the session key, uh it will create a new session key, sorry, and store your session data in the database so you can access it later. And thanks to the session middleware, uh we can also use it on on our views already instantiated as a request attribute. Like we saw earlier in this talk. Uh but and when the session middleware is instantiated, it gets the session store. Uh based

15:16

on what we define on our settings. In our case, the database backend and it saves uh it and save it as an attribute. When the process request is called, it tries to get the session ID cookie to recover the session from the database. But if you are accessing the site for the first time, it will be none and the new session store will be created. It's also thanks to the session midware that after we change uh the session store object, it gets saved into the database. Um let's look at the simplified code. Uh so We get if our session was modified access or if it's empty Uh

16:01

if it was modified, we get the session expire date. If we set that to none, uh the session will expire every time the browser closes. If not, uh we're going to It will going to be expired uh with the default value we have on our settings. Uh it the default is two weeks. So, but let's keep in mind that if the the the modified flag will only be true if we modify the session itself. So if we modify the session full here To bar or delete it, it will be modified. But we if we modify uh an item of the session full, it won't be modified.

16:46

So the session won't be save again, save it again So after saving the sessions session, Django will set the cook and send it to the user so we can use it again on the next request. So we now understand how login works, how authenticate calls authentication backends, how authentication backends are implemented. And we understand sessions and how they work. Now we are going to see how those pieces are glued together and to provide the authentication feature in Django. And I'll talk about four different scenarios. Uh so authenticated user, authentic no unauthenticated user, uh unauthenticated user with a session session change, user authentication, and logout.

17:36

So unauthenticated user. When our unauthenticated request arrives in uh in our Django's uh project, the first middleware to be used is the session middle. It tries to get the session, uh and since it's your first time in the site for a while, you don't have the session itself, so it creates a new session store object with a session key none. After that, we go to authentication middleware. It checks if you already have the session middlewall because it's required. And tries to assign a user to the request. Since you're not authenticated, it will be an instance of the anonymous user This get functions uh function here calls uh

18:21

actually calls the authentic uh authentication backend uh get user. Oh sorry, the g this get user function actually calls the authentication backend get user function uh that we defined uh on the beginning of the talk. So after that we get to our view, it does its job, renders what needs to be rendered, and we go back to the middleware. So the session midware verifies that this if the session store was modified, if what if it was accessed and if it's empty. Since we didn't change anything on our session, nothing will happen here. The cookie won't be set, and we don't have a session actually.

19:07

Okay. So next case is unauthenticated user with a session change. So, until we get to the view, it's basically the same. Um the session readware tries to get the session, it can't, so it creates a new one. The off middleware binds the anonymous user with the request and then we get to the view. And in the view here I'll change like a bit of the session. Just to see what happens. I'll add my name here, Renato, and the view wraps things up, returns what needs to be rendered, and we get back to the session middleware So since we added something on our session, it is modified, it is accessed, and is not empty

19:55

So we will calculate the session uh expire date, we 'll save the session, and we will set the cookie in the response uh to be attached to the browser. As we can see here on our um developer tools of choice. And now we have a session attached uh to an anonymous user. Uh let's see what happens when that user logs into the system. So again, we go over the session midware, but now we have a session ID cookie. Uh we get that and create a new instance of the session store with that key. We follow to the authentication midware and it will bind the anonymous user uh with the request.

20:41

Uh and we get to our uh login view. Login view is a form view, and like we saw on Felipe's talk, uh it will call the isvalid function on the authentication form. That is valid function actually calls the errors property, which calls the full clean method, which we'll call the clean method. And that's where the magic happens. We get the username and password, and we call the authenticate function Like we saw earlier, the authenticate function we reiterate over the authentication backends. We only have one, so it will check the password and we it will return the user, uh the authenticated user to the authenticated function.

21:30

Which will return the user to the authentication form with the backend as an attribute. And the authentication form will be valid because we don't raise any errors, errors here. The post receives true from the form is valid, so it will call the form valid function, which will perform the login itself. So we uh if it will verify that the user uh the authenticated sorry it will verify if the user has the authenticated authenticated session key, it's hard Uh it doesn't, so it wasn't authenticated before. So it will cycle the clean the key. This process uh actually gets the previous data we had on our session.

22:19

Creates a new key and keep that data again. So when we log in and we have something on our sessions, it will be maintained. We store the session key and the backend in the session, and we attach the user to the request. And now we can go back to the session middleware. So in the session middleware uh our request was accessed, modified, and is not empty. So we'll set the expired date and we will save our session so the user can access through every request and we set the uh session ID cookie. And then we are logged in. Now uh to log out.

23:05

So again, the request arrives in the session midware, it gets the user session key, uh, and it's And it instantiated a new uh session store. The request then follows to the authentication midware And so it gets the user, and this full function calls this get user function here. Uh it will get the user ID from the session. Uh so we we store the user uh private uh primary key in the session key value of our session. It will retrieve that. Uh it will get uh the backend from the session actually uh also and uh for each of the authentication backends

23:52

It will load the backend and try to get the user. Uh if we get not sorry, not for each. Uh for the backend we had defined, it will load the backend and get the user. Uh and it will return the user to our previous uh off middleware get user function. So we get to our logout view with our user in the request. It will call the logout function, which will flush the session and replace the user back to uh in the request to the anonymous user. And then we follow again to the session midware. The s session is now empty because we flushed it actually

24:37

flushes is a clean and a delete. So it erases the data from the session and deletes the key. So the session is now empty and CIST we still have the session ID cookie on our cookies. It can be deleted and we are fine and log it out. Thank you so good.

Questions this talk answers

What are the different types of authentication?

Authentication can be based on a credible entity’s proof, comparison with known attributes, or external documentation. In digital systems, authentication factors are categorized as knowledge, possession, and inherence or biometric factors.

Discussed at 4:56

What is the difference between single-factor and multi-factor authentication?

Single-factor authentication uses one category of credential, such as a username and password. Multi-factor authentication combines two or more independent credentials for greater security.

Discussed at 5:44

How does Django’s authenticate function work?

Django’s `authenticate` function iterates through the configured authentication backends, passing them the supplied credentials. It returns the authenticated user when a backend succeeds and stops if a backend denies authentication.

Discussed at 8:04

How do Django authentication backends work, and when would I use one?

Authentication backends provide a common API for authenticating against different sources, such as a custom single sign-on system or OAuth 2. A backend defines methods including `authenticate` and `get_user`, is added to the settings, and Django handles the rest.

Discussed at 8:04

How does Django login keep a user authenticated across requests?

Django’s `login` function stores the authenticated user’s primary key and backend in the session and attaches the user to the request. The session cookie then lets Django recognize the user on later requests without asking for credentials again.

Discussed at 10:30

How do Django sessions work?

Sessions let Django store temporary, per-browser data across otherwise stateless HTTP requests. Django’s default session backend stores session data in the database, while middleware loads it from the session cookie and saves changes at the end of the request.

Discussed at 11:20

How does Django preserve existing session data when a user logs in?

When an unauthenticated user logs in, Django cycles the session key rather than discarding the existing session. It keeps the previous session data, then stores the new user ID and authentication backend in the session.

Discussed at 22:19

What does Django logout do?

Django’s `logout` function flushes the session, removing its data and deleting the session key, and changes the request’s user back to an anonymous user. The session cookie can then be removed from the browser.

Discussed at 23:05

Note: We understand that names change, people change, and bodies change. We respect each individual's journey and privacy. If you have any concerns about a video or need us to remove content, please don't hesitate to contact us. We will handle your request with care and promptly address any issues.

More videos from DjangoCon US