Closing session
Published June 13, 2025
This video features Justin Mayer at DjangoCon Europe 2022 in Porto, Portugal.
Add Multi-Factor Authentication (MFA) to Django in Mere Minutes by Justin Mayer
Passwords alone can’t protect us. We need multi-factor authentication, which doesn’t come with Django out of the box. But we can add MFA to our Django projects in just a few minutes, giving our users the ability to protect their accounts with Touch ID, security keys, and one-time passwords.
Justin Mayer argues that SMS and email-based MFA are weak choices: they create privacy and reliability problems, encourage code sharing, and can still amount to single-factor authentication when an email account can reset the password. He recommends device- and app-independent TOTP and WebAuthn, noting that WebAuthn is the only option discussed that resists phishing, while passkeys may eventually combine strong security with better usability. He demonstrates adding the Kagi Django app to a fresh project, configuring its URLs and settings, and enabling WebAuthn keys, TOTP, and backup codes in a few minutes, including how to override its templates for custom styling.
Summarised automatically from the transcript.
Automatically transcribed, so expect mistakes in names and technical terms.
My name is Justin Mayer and the first time I attended a developer conference was at DjangoCon in 20 in the United States in 2011. So I'm really excited to be back here at DjangoCon in Porto. I'm originally from Los Angeles, California, but for the last few years I have spent the nicer months on top of a mountain in the Alps in Italy. where my colleague Luca and I have been working on Fortressa, which we think of as the App Store for open source. Just really briefly, it's a place where you can install web applications that would normally be a pane to install. You tap a few things and you get the ability to have analytics that has better privacy than Google Analytics. You can have better uptime monitoring.
We just try to make it really developer-friendly and make it easy to improve the software that you're developing. And we have some really cool things in the works for Django people. So if you want to see how it works, you want to know more about it, just reach out and I'd be happy to demonstrate. Apart from working on Fortressa in my spare time, I maintain a few open source projects such as Pelican. VirtualFish, and a few pluggable apps for Django, including one that I'll talk a little bit about today. Today I want to talk about why multi-factor authentication is important. how not to do multi-factor authentication and how you can add what I consider to be proper multi-factor authentication to your Django applications.
So, first of all, why is multi-factor authentication important? It's important because some people do bad things on the internet, and that causes a lot of damage. How much damage? Let's take a moment to count the financial losses. So in 2019, estimated losses were 2 trillion euro. That's nothing compared to what it will be in a couple of years when we reach ten point five trillion euro Now, I thought about this for a moment. I'm like, okay, that that seems like a big number. What is global GDP? What is the output of all the planets economic activity? Well it's about a hundred trillion So that means we have a loss ratio of about 10% of global GDP
to you know criminal activity and other crimes that are committed on the internet. So that is a staggering ratio, a staggering proportion. So clearly usernames and passwords are not good enough to prevent this kind of damage from happening. So the software industry has developed several ways of mitigating those losses. Multi-factor authentication usually involves some combination of something you know, like a password, something you have, like a key, and or something you are, like a fingerprint or a face identification. This is not a new concept. I arrived at my BNB last night and I was delighted to discover this. This is sitting in the living room of my BNB
and it has a place to put a key and then above it there are three dials to to enter your combination and then you can open this safe. I have no idea why this is sitting here in my in my BNB. I've never seen anything like it before. It's amazing. I want to take it home with me. The universe is saying something to me that this appeared in my BNB when I got there. So let's talk about some of these something you have factors. SMS is one, you uh you know you put in your phone number when you When you enable this uh this function, it sends you codes, you enter the codes, okay, you're authenticated. Email tokens are similar. You log in with the username and password, and then it says
check your email and tap on the link, and then you tap on the link, and then you get in. One-time passwords, otherwise known as time-based one-time passwords, are you've probably seen these before. You install an app or you use an existing app and you generate some six-digit number that's tied to some other cryptographic secret, and then you enter in this number and then you can log in. And then there is web authentication. Which is usually tied to a USB key. Not not always, but but up until this point that's been the most common way and the hardware secrets the secrets are on that hardware and it makes it very very secure for a variety of reasons. So now is the portion of the show where I ask you a few poll questions. So please bear with me and raise your hand when appropriate
Raise your hand if you have some account on some website, any website, where you currently use one-time passwords via an app on your phone or computer to generate six-digit numbers. Okay, so that's a good number. Wow, that's like 70, 80%, uh maybe even higher. Okay, now raise your hand if you have some account on some website, any website, where you currently use web authentication as an authentication factor. Okay, exp definitely a lot less as I would imagine. Numaibi 25-ish percent. Okay, good to know Now raise your hand if you've ever added SMS-based multi-factor authentication or email-based two-step login to an application that you've worked on. Wow, okay.
That is a big number. Maybe uh 35 -ish, 40%. Okay. And if you raise your hand just now, I am going to explain the reasons why you should reconsider your life choices. Um I I I'm kidding. C kind of. Um so Okay, one last time and then I'll be done with this. Raise your hand if you ever wanted to use one-time passwords or web authentication on some account you use, but you can't because that site doesn't offer it. All right, pretty much most of the room. Cool. That's also great news, you know, because if we don't demand it, it's not going to happen. So SMS and email two-step logins has a problem and that means you can't easily share an account
Now okay, you could say, well, you you shouldn't be sharing accounts. Well actually there are some good reasons, legitimate reasons to share an account. Maybe you're your romantic partner and you have an account somewhere and you need to be able to get into that account. You can't because the code is now going to that person's phone or email account and you don't have easy access to that. It could be a business partner 's, same same problem. And you have this dance of the hey can you send me the code you just received? Sure, here it is. So not only is this a hassle for everyone involved, but it also conditions people to sharing these codes, which opens the door for attackers to send spoofed messages, pretending to be someone that you know and asking for these codes. Which is a thing that is very real and happens sadly every day.
So that's email. Um SMS-based MFA is terrible. Um Some people will say, oh, but it's better than no multi-factor authentication. And this is nonsense. Those are not the only two choices. This is a false dichotomy. And it's a low bar. We can and do better. And so why? I don't have enough time to go into the real details But the security of multi of uh SMS-based multi-factor authentication is bad. I uh can refer you to if you want to know why, just reach out and I can tell you why it's bad. It's also a privacy violation So, you know, Facebook famously years ago said, okay, we're gonna offer you great multi-factor authentication. Just give us your number.
Don't worry, we're only gonna use it for multi-factor authentication. We promise Everyone knows that was a lie. It ended up being a big lie and they were caught in that lie and they ended up using it for all kinds of other ad tracking and gross things that they shouldn't have been using it for. So it's just not a good thing to have to be be even asking your customer your customers or users to be you know putting in their phone numbers. It's a GDPR problem also. It's just a bad idea. Even the sites that offer better options like one-time passwords and web authentication, they will often force you to hand over your phone number. and set up SMS-based multi-factor authentication as some kind of fallback. And so you have to do that in order to use the better ones.
Which weakens the security advantage of the better ones and once again violates your privacy. So that's um SMS. Email-based two-step authentication is a little bit more private. You don't have to hand over your phone number. But in other ways it's worse than SMS. It's slow. When you want to log into something, you don't want to wait for some email to arrive. That could take 10 seconds, it could take 10 minutes. That's not something you want to do when you're trying to log into someplace. Email delivery is not reliable. Sometimes it arrives, sometimes it doesn't. This is not a way to set up an authentication system. It's also not really multi-factor. Because of password reset functionality, this is in some ways still single-factor authentication.
Why is that? Well, it again like we talked about, something you know, something you have. Well, here this just ends up being something that you have, which is your email account. This method you know protects against uh you know if a site has a database breach and they get all the passwords, okay, well this is This protects against that, so there is some value. But if someone has access to your email account, they own you. They can just reset your password. So they have that now, and then they can use the two-step login token, and now they have that, and now they're in their bank account. So the stakes have become even higher recently. as companies are starting to require that you enable multi-factor authentication to use their services, which sounds great, except that their MFA implementations are a trash fire
generally. And they're dependent on SMS and email, and this is not the world that I want us to live in. So those are my notes on SMS and email. for it for MFA, uh for multi-factor authentication, now I'll mention two quick things about one-time passwords and web authentication. One-time passwords should be device and app agnostic. Many companies require that you use a specific app to use their one-time password-based multi-factor authentication. This is insanity. It's math. The math doesn't care which app performs the cryptographic functions. So if you require users to install and use a separate app That you already have one you like, you want to use it, but they're requiring you to install a separate one in order to do this thing on their site.
Uh even though you already have one you like, you are making the internet a worse place to be, and I want you to not do that. Web authentication is the only method that protects against phishing. All of these other things, including one-time passwords, are gri you know uh can be phished. So You set up a fake site and you trick someone they think you think you're on the real site, you're on a fake site, you put in your one-time password, now they have that, and now they have 60 seconds or so to get it into where they need to go, and now they're in your account. Web authentication is more secure, but it has usability problems. You know, it's usually a USB key. You have to push it, you could lose your key. It's not great for normal humans, which is why when I did this poll, I found that most of you, you know, don't use it.
Thankfully, web authentication can now be used without USB keys. It's now being integrated into other solutions like touch ID and other ways that some might argue are slightly less secure. But even if that were true, this is made up for by much higher usability. So I think it's a great way of getting web authentication into more people's use. It's a very worthwhile trade-off. So I get frustrated by the glacial progress of this of this whole multi-factor authentication thing. All of my banks my healthcare providers. Five years after I started presenting talks about multi-factor authentication, nothing has changed with any of the sites that I interact with.
Not one of them supports one-time passwords or web authentication in any kind of sane manner. And I want to do something about that, and so I've been working on a solution for Django. One of the cool things about social media is that you can encounter people with shared interests all over the world. One of the other attendees of this conference, Remy Hoopsha. replied to one of my tweets a while back and I mentioned that I wanted to build a better multi-factor authentication solution for Django. So uh we've been collaborating and we built this uh app called uh called Kagi, which is the Japanese word for key. I spent a lot of time in Japan and and speak the language, so everything I name seems to have a Japanese name But I wanted to build this because it's based on a Python library called uh WebOffN.
Um it doesn't use the FIDO2 library. I I just prefer the technical implementation uh web off end a little bit better. And also that was the library that was chosen for the work that Trail of Bits, which is a very well-respected security company. They use that library to implement second multi-factor authentication for PyPI. And I really liked the work that they did, so I wanted to emulate how they how they did it. So now I'm going to show you how to add multi-factor authentication to a fresh Django product project in just a few minutes. I want to do this live, but in my experience, presentation projection systems aren't really optimized for live demos, so I recorded myself doing this to a fresh project, which you will be able to see here in real time.
So I'm creating a virtual environment. I'm using fish, so if you see weird things, it's because it's fish, but most of it should be standard. I'm now in uh pip installing Kagi. as well as well as its dependencies including the latest Django 4. 1. 1. I'm creating a new project. I'm just calling it core just to have something in the in the project that makes sense renamed the overall project Kagi demo and the first thing I'm going to do is start editing some of the settings that are automatically generated by Django so that we can start using Kagi. So the first thing to do is to add Kagi. to the your installed apps. There will be delays where I don't say anything because I'm waiting for the next thing to happen and this is one of those times.
Next is we need to add a place for templates, just because I want to um we need to add a base template as you'll see in a subsequent step. And it could be any base template. There just needs to be a a template called base for us to be able to override and extend. the things that um that Khagi does. So now we need to add some Kagi specific settings. And one of those is the um you know loggy uh log um the login redirect URL. So once you have successfully logged in, where should it go? We're going to have it go to the multi-factor authentication settings just so we can get there quickly and start configuring them.
We are defining our login URL route and we are setting which IP addresses can be you know should be allowed because we are doing this all on localhosts. just using the loop back address. We need to set some web authentication specific details as well such as the relying party ID which I believe can really be anything we're just calling it localhost or maybe it needs to be the actual domain, I don't remember. So the problem with uh with doing things and then forgetting how you implemented them. We have a The really relying party name, again, totally arbitrary, and then an icon URL, which I'm just using some placeholder
um as a as the icon URL. And those are all the settings that need to go into into this file. And then the next thing we need to do is make some edits to the URL routes I need some elevator music. And one of the things you'll realize in a moment. See if you can spot the mistake that I make. That'll be a fun project for a fun activity for everyone. Because there's one in here. Or at least there will be. So we're adding some um um some paths so that when the user uh logs in they are um um
So I'm waiting for my own extremely slow typing to happen. So we do um you know a reverse lazy um uh redirect to the login page. Was I drunk when I did this? I don't remember typing this slowly. And then we we include all of the Kagi provided uh URL routes and then we and then we namespace them. And that should be the only edits that we need to do here. Um but I made a mistake when I did this. Did you see it? That's right. Um
so here this is I copied a um this is just a base template. This could be anything. And I copied this from the demo project inside the Kagi repo. Um but it's just a base template. It doesn't really do anything Kagi specific. So we need to run migrations, but we're gonna run into the error that you all were smarter than you know than me. So you you figured out what I did wrong I could have you know done some clever editing to make you know but I wanted to really show that this is almost like a live demo. Going to fix my silly mistake. And import the redirect view. And now we should be able to run our migrations.
Yay, now we need a user. So going to create our our user so we have something with which to log in. Great, so now we have everything we need to start the application. And now we switch to our browser and we will just go straight to localhost 8000. Put in our username and password, and the first thing we see is the multi-factor authentication settings. So we're going to tap on web authentication keys, and we don't have any.
This is a list of the zero keys so we are going to tap add in order to add one. So first we're going to choose a key name. I'm going to call this a solo key which is the brand of my key. And then I hit add. You could use touch ID, but instead I hit cancel or not cancel, but no, I don't want touch ID, I want my hardware key. So that's what I did. I put my finger on it, and then it adds this key to the list, as you see here. So we've added our our first second factor. So we now have that as a as a factor for logging in. I'm also going to take this opportunity to add a one-time password. So obviously you won't be able to see the phone portion of this, but the phone portion is I use my OnePassword app. I hit you know add one-time password.
It has a camera, I scan the The QR code, it then starts generating the six-digit numbers that refreshes approximately every 60, 30 seconds, maybe 30 seconds. And once I see that code, I go over and to this token box, I put in the six-digit number, and I add add that uh add that device. So now I have two different ways of logging in. If I have one device with me, great. If I don't, I can use the other one. So you can see here that it shows the status. We have web authentication enabled and we have uh one-time passwords. And now I'm going to generate backup codes. These are important if you have none of the other two. You can save these backup codes somewhere safe.
You can print them out, put them in a safe in your house. However you decide to preserve it, but this way if you have like I am locked out, I've lost my phone, I've lost my my web authentication key, you have a way of getting in. So now we're going to see what happens now that we've enabled those things. So I log out and now I'm going to log back in And this time the flow is different. Now we are prompted to enter in some other factor. I'm going to use a one-time password in order to do that. Tapped the wrong button. And um here we are. Um now we're in the account. So um this is This is you can see how this uh this works.
And um yeah. Let's see, oh that's right. And then the next step is I'm now going to copy all of the templates that are provided by Kagi that would normally just be installed for you, and they are installed for you, but I'm going to copy them to the local project so that I can override one of them. just so you can see uh you know how that would work. Obviously the templates that are provided are totally unstyled. You know, they're not particularly attractive. That was done so that you know you can and do the things you need to do. So here I've copied over those templates. I'm going to edit one of them and just quickly change the title of this page. And I noticed that for some reason in the stock templates, the backup codes are in the middle.
So you have web authentication, backup codes, and one-time passwords. That seems a little weird to me. Should probably change that, but at least I'm changing it here in this local project. And once we make that change, and then we flip back to um to our uh to our browser, we should see that we refresh the page and we see that those changes have have taken effect. So that's how you can override the stock templates and customize them for what you need to do. So the templates included yes sorry, I already mentioned this that they're unstyled. Um you know when I started developing uh when we started developing Fortressa, I'm sure you will be unsurprised to hear that it was important to me that we integrate multi-factor authentication via Kagi from the very beginning. So I wanted to give you an idea as to what it looks like when those templates are styled,
because otherwise it's a little um unclear, I think, as to how what that looks like. So this is for Trussai, we have these different services that you can install, but we're going to go to your profile, and here I'm going to go to the security section. And here's a much nicer list of those things. And we're going to add a one-time password, same flow. as you have already seen, but it's just a nicer experience when you take a moment to style the templates to fit your layout and your styling. So that's um yeah. Um I know that we're a little short on time, so I'm just gonna skip ahead because you you get the basic idea
So in terms of future plans, Remy and I would like to find some time this week to work on Kagi a little bit, including upgrading the web authentication library to a more recent version. We want to then correspondingly update uh some tests because we like to maintain 100% test coverage. In terms of future plans, another thing that I think would be exciting would be to implement support for pass keys. So up until now we've been talking about multi-factor authentication as an additional factor to username and passwords. Well one of the things that people are trying to do is to get rid of those other two things so that you just have the pass keys. So there are no more passwords. And this actually can work.
Both Apple and Google are implementing support for this. The latest version of Safari that just came out a week or two ago, Safari 16, includes support for pass keys. Here's a link where you can learn more about it. It's a little bit more Apple specific, but I'm sure you can find that for Google-related things as well. I think it's really exciting. I think it's really going to improve security. But more importantly with good usability. I have some reservations about it because you know with username and passwords and multi-factor as it stands the way I just described it. It's not tied to a particular company or uh or architecture and this kind of is, and so I don't love that, but it's also really great combination of security and usability, so I at least want to be open-minded about it.
and see if it could be a good solution for um for users. So today I wanted to ins to really inspire you. I wanted to explain why I think this is important. I wanted to explain how easy it is to do it. I mean You could do this. I I basically just did it in five minutes. Took me a couple extra minutes to flip back to the browser to show you how it works, but you could actually do this in five minutes. So I will announce on Twitter when I've posted these slides, so you can follow me if you want to know when they're available. If you want to know more about multi-factor authentication and Kagi, if you have any questions, ideas, or suggestions please come find me here at the conference or reach out via via Twitter or via my site. And thanks for coming and thanks for listening.
Usernames and passwords alone are not sufficient to prevent the major damage caused by online crime. MFA adds another factor based on something you have or are, alongside something you know, to reduce the risk of account compromise.
Discussed at 1:32SMS MFA has weak security, creates privacy and GDPR concerns, and can expose users to social-engineering attacks involving shared codes. The speaker argues that it is not merely a choice between SMS MFA and no MFA; stronger options are available.
Discussed at 7:00Email login codes are slow and unreliable, and password-reset functionality means that access to the email account can often provide both the reset password and the login token. In practice, this can reduce the method to dependence on a single email account.
Discussed at 8:32The speaker recommends device- and app-agnostic time-based one-time passwords and WebAuthn. WebAuthn is the only method discussed that protects against phishing, while newer implementations using Touch ID and similar built-in capabilities improve its usability.
Discussed at 10:08Install Kagi and its dependencies, add it to `INSTALLED_APPS`, configure the required settings and URL routes, provide a base template, and run the migrations. Kagi then provides screens for registering WebAuthn keys and one-time-password devices, authenticating with them, and generating backup codes.
Discussed at 14:05Copy Kagi's supplied templates into the local project and edit them there. The included templates are intentionally unstyled, so they can be changed to match the application's title, layout, and visual design.
Discussed at 21:50Note: 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.
Published June 13, 2025
Published June 13, 2025
Published June 13, 2025
Published June 13, 2025
Published June 13, 2025
Published June 13, 2025