← Back to Show Notes

Transcript: Authentication

Hi and welcome to another episode of Django Chat. I'm Carlton Gibson. I'm here again with

Will Vincent. Hi Carlton. Hi Will. We're going to talk about authentication this week. Will,

what's authentication? I'm glad you asked. So authentication is how you sign up and log

in to a website. It's commonly confused with authorization, which is permissions. So for

example if you know some people have access to some parts of the site and others don't to others

that's authorization authentication is just how do you log in and say yes i'm a user of this site

and django has a lot of options here a lot of built-in a lot of third parties so i think it's

a lot to unpack about how to do it but almost every website you're going to need authentication

so maybe we'll start so i have an entire 40 minute django con talk on authentication within django

REST framework, because it can be confusing. So we'll link to that. And I'll try not to repeat

all those points. But a distinction is between Django and Django REST framework. So Django

itself, web framework uses sessions and cookies. So that is where when you first sign into a site,

you send your username and password, which creates a session object on the server and the server

sends back a session id so that id can be linked and so that is what's passed back and forth that's

built into django itself that's the predominant pattern with websites but as we'll get into with

apis things are a little bit different but that's what the first thing you should know is sessions

and cookies that's what django uses that's what basically every web service uses it works i don't

think there's much to add on that no i mean so the so django has contrib.auth which is where you get

your user model and you can create a custom user model if you want to um now we've talked about

this on another on one of the first episodes i use the bog standard model um because when i

create a new project i just want to get going my idea is my thought user profiles well i use the

the bugs the user model that comes with django okay and then if i need to store additional

fields on that i'll create a profile model with a one-to-one field and django does have this

ability to create a custom user model and they kind of recommend that you do because if you want

to customize it later on it's quite a difficult thing to do now over the years I've come around

to the conclusion no just use it and stick with it but that's my my take yeah yeah there's well

there's and this is like the first point of confusion for people is there's three dominant

patterns for doing this there's as you mentioned using the built-in user model and creating a

profile model for additional fields there is and then there's creating a custom user model which

came in i think django 1.6 something like that there you you basically there's two ways to do

it you can create a copy basically extend the built-in user model with abstract user

or you can abstract base user where you go a level deeper and so this is what you do if you want to

you know so django uses username email password because that was the dominant pattern whatever

12 12 back in the day and there are ways to hack around that but most sites these days just want

email and password and so this is some of the reasons why you might fiddle around with this

but again I think I've come around to your point of view I mean I use custom user models but I

think it's easy to confuse you don't want a complicated sign-in you may want to add all

sorts of information later when someone has a profile such as age and this and that but you

don't need that when they sign in so that the user model is only for signing up and logging in

that's it then you can link everything else to it yeah and the big danger for me with custom

user models and i've seen this i've seen this is that teams create a custom user model and then

they start adding field after field after field and it becomes this and what you really want is

a separate profile model for all of that data which links to your user model because your user

model is for authentication you want to keep it nice and small with just a few fields and for me

another benefit of using django contrib.auth's user model is that it stops you doing that is

it stops you falling into this trap where you added you know like this massive um life biography

field to your login model so do you do you do something to remove the username part of that

or do you just use yeah well i actually quite like usernames i'm i'm i think i'm old you know

i'm like get off my lawn um so old yeah no well you know i'm i'm nearly in management age um

as my talk in heidelberg in django coin europe a couple of years ago was all about but um yeah

by the way that's that's a fantastic talk that's i first uh learned about you and reached out to

you about that talk i sent you an email saying i really resonated with that talk about yes that

was called growing old gracefully and it's about being a programmer as you get older and so anyway

i recommend that because it's you know it's a challenge in our industry but so i've used and

still use django all auth which is one of the um third party packages around this and what that

enables you to do very well is it sets up a custom authentication back end which enables you to use

emails as your login so one of the reasons perhaps i think probably historically the main reason

that custom user models were brought in was because people wanted um email logins but on

Django contrib.auth user, the email field is not unique. So you have to enforce that somehow in

order to have a unique field for login. And all auth puts all the machinery around that for the

custom backend. And when you create a new user, making sure emails are unique and that they're

tied to a user in a unique way such that you can use logins with email. And so if I want email

login, I use all auth for that. But I still like usernames because quite often you want a display

name you want you know a forum or a um you know an ability to see what user is without using their

real name and without using their user id which is potentially sensitive and so i still like

usernames yeah i think the other major package is django registration um which has also been around

for quite a while and it's still being worked on and what yeah what that does gives you sign up

forms and it handles this confirmation flow. So normally you want a user signs up, you get an

email and you have to click the link to verify you're real, right? So Django registration gives

you all of that. And it's good. It's by James Bennett, who's a big long-time contributor to

Django. And a member of the DSF board, actually. If you've used other frameworks, sometimes just

they give you the like the signup page. So Django does not, which is partly why these things come

about. Django does give you the login and logout forms, but you have to do the signup page yourself.

So that involves, you know, views, URLs, templates, or using one of these third-party packages.

That's not always the case with every framework. I mean, I appreciate that Django provides that

flexibility, but I think it is a little bit, it's more, a little more effort than some other

web frameworks on this part yeah and when i was first learning django i i was like why

why aren't there templates for this that was exactly my thought exactly and but if you type

if you type django registration templates into google it's amazing you'll find very quickly that

these all these do exist but yeah i mean i mean it's the tension between flexibility and ease of

use uh you know django is eminently customizable but it means a little bit more effort which you

know you appreciate as you advance in your career but getting started it's like oh why isn't it do

it the way you know rails does it or something yeah i don't know i mean i still part of me

you know if i start a new project and i still i come up against this problem oh i'm like oh i've

got to dig out these templates from and if you want to like why doesn't this exist if you want

to save time on this there are some django starter projects out there django cookie cutter is the

largest one um i have one as well django x which is a little bit simpler which just gives you

sign up forms email option um because it's sort of the same i do the same steps in every project

and it does feel a little bit like doing the same thing over and over again but people's use cases

are different and django allows for that so that's why these packages exist yeah but if you are just

looking for a sign up templates there are as you say these there are these examples which you can

either just use as you're starting off your project or if you've already started your project

you can just copy the templates across and they make a great template a great starting point a

great foundation you can then they do and customize and the other part of this is you know because an

email will be sent you need to configure email in django so that's um you can usually when you're

getting it testing it locally you can have it output the emails to your your console your

command line but then you need to plug in an email service and that's another hurdle for people

learning how to do this that once you've done it you realize oh it's just a couple lines in your

your settings.py file but the first time it's confusing um i cover all this i cover all this

in my book django for beginners but i'm sure you there you are there you are but yeah i mean that's

another thing is like well how do i send an email well i have to configure smtp well can i just use

gmail say well yeah well you used to be able to but what are the you used to be able to but what

are the configuration details yeah you can't do that anymore no they they used to be able to just

use gmail i may be a year dated with this but they changed it around so you you have to jump

through all these hoops and you basically can't do that anymore you could three three four years

ago that's the way i did it oh okay google changed something around that so you you really need to

just use a service you know centigrade mailgun there's a whole whole host of them um amazon's

ses simple email service very good it doesn't really matter which one i mean well like yeah

all of them they all do the same thing if you type in if you type in whichever back end you

want to use django send grid like there'll be a third-party package which wraps it up in an email

back end and you just put two lines in your settings file and configure this and it'll just

work yeah yeah i mean email we could do a whole episode on email but it it can get a little

complicated but with smtp you basically get a an api key and you just a couple lines in your

settings.py file so you sign up for the account you plug it into your settings.py file you tell

Django, okay, output emails to SMTP, not the console and away you go. Anyway, so Django gives

you lots of flexibility here, but there are these hurdles if you're learning it for the first time,

but then later you appreciate them. So let's talk about APIs. So this is where it gets real

because now you got to, you don't just, you know, I didn't know about Sessions and Cookies

and Django for, I would say at least a year into it because I didn't need to. I just, you know.

Well, it just works. It just works, right?

Oh yeah, it just works. So you don't need to think about Sessions.

django is my first web framework so i didn't know anything about anything um so you know that's why

i up front mentioned sessions cookies and this matters with apis because as well people think

oh you know well couldn't this be better in my day you had to do all this by hand you had to you

know send the set cooker header and it was you get this wrong every time and this is where django

doing it for you and providing the auth framework and the sessions framework and it matters so much

because you won't make these mistakes

and you don't have to build that stuff.

Right, and you really don't want to mess this up.

You really don't want to mess up this part of your site.

Yeah, you know, I mean, you know,

and you'd get session leakage problems

and it was just a nightmare.

And well, you know, Django, that's,

anyway, we've talked about this loads of times,

but that Django provides it for you

is just such a resource, such a, you know, blessing.

Yeah.

One of a better word.

So Carlton, co-maintainer of Django REST Framework,

why don't you explain,

why are there four built-in methods

and not just one, not to mention all the third-party methods.

What's going on there?

Well, authentication is complex, right?

So back in the day, we used to use HTTP basic auth,

which your browser still does this, and I still use it quite, you know,

not all the time, but from time to time I'll still be like,

ah, I just need some auth, HTTP basic auth,

because then you get that little browser-delivered pop-down

and you can just type a password, and it's great for bootstrapping something.

But sometimes you want to send the password and the username with the request

and have it authenticated so that would be http basic auth sometimes if you're in a browser you

can just use the same session auth that django uses for a normal website so for instance if

you're using an api to augment your website so say um i don't know you've got a form which you

want to augment with ajax and you you use an api endpoint to submit the data so that you don't

avoid a full page refresh or whatever then you would just use session auth and if you can use

session off do because it's the existing cookie the existing login agreed yeah it's it's fantastic

and then you want to go on to well what about multiple devices and so from your mobile phone

from a native app on a mobile phone you have to use some kind of token um which is like a it's

like a key so authentication is something you've got it's like i've got a password or i've got a

token with that with a with a long number which you identify uniquely identifies me no one else

has got this.

So an app can authenticate with the API

using a token of some kind.

And Django REST framework ships with a very simple

token authentication implementation.

It's not designed for building Twitter

or building Facebook or building Instagram.

It's designed for small sites

who just need a very simple implementation.

Then there are more complicated ones.

So something like JavaScript web tokens

are very popular now, right?

Tell us about that as well.

Thanks for punting that one to me.

No, but well, they enable you to do things like refreshes

and they enable you to use multiple devices,

but you talk because you wrote the book.

I wanted to ask you, what's up with remote user auth?

Because that's the fourth built-in method.

And I have only an abstract understanding of this.

When I gave my talk, a bunch of people asked me questions, and I found that people are using this in the real world.

But when I tried to just configure it myself, I couldn't do it.

The times I've used this is in enterprise environment.

And Django itself has remote authentication, and so does Django REST Framework.

And the idea is that say you're, I don't know, an big company and you've got a single sign-on server or something where people can authenticate, you can go and get an authentication from that third-party authentication server.

And then you can use that as the authentication source and say, yes, this is authenticated via that third-party service.

These things are very useful in those kind of environments where you've got an existing login.

So maybe you've got a Django app already that has users in it and has people authenticate it, and you want to create a separate Django app which uses the user database from the other service.

Well, then that would be a use case for remote user authentication.

Okay.

You know, I remember there was people from University of Texas, Austin, which has a massive site and uses Django, and they're one of the folks who use it.

They're really big in tech.

Yeah.

Okay.

Okay, good.

so four built-in methods and just to reiterate so basic auth is the first one that's just email

and password sent in clear text um in well username and password so it's your username

but all right okay and they are sending clear text but this is why we're all using https

right but that's why it's because that puts in as part of the request and so if it if it's not

encrypted they would be visible over the wire exactly so basics fine for get up and going

session will be the next level use it if you can so django uses token auth again so the what i don't

know if you mentioned the issue with why can't you use sessions with multiple devices is because

each session is unique so that's why you have a token for you know mobile setting remote user

auth is enterprise ai and then you get to javascript web tokens which you'll see people

saying oh you have to use javascript web tokens so this is a more complex token basically there's

long tutorials on it. It's Base64 encoded. You can wrap up all sorts of information within it.

The dominant third-party tool for doing it with REST Framework is Django REST Framework Simple JWT.

And in my talk, I talk through how to implement this. And there's a source code that goes along

with it that has a working example. So yeah, the main reasons is the token auth within Django

framework is pretty basic so you may not want you may want your tokens to expire over some period

of time in fact you probably do because otherwise if it never expires if someone grabs your token

they have full control and javascript web tokens provide a lot of extra stuff but i would say don't

just jump into it unless you need it keep it as you know both of us agree keep it as simple as

you can you can change this as needed but don't don't just jump into some complex jwt you know

there's all sorts of fun, cool ways you can customize stuff. But if you don't do it unless

you need to. Yeah, I mean, if you know, if you're building a, if you're in a sort of team environment

where you're building a public facing mobile web and mobile application with multiple clients and

multiple platforms, and you're in a team, and it's a proper business, and it's, you know, as I say,

public facing, then JWT is probably something you want to be investing the time in and looking at.

But if you're building a smaller app, which is kind of just your business team,

it's only got a small number of users, then tokens are fine.

The token auth that Django has very much ships is fine for that.

But it depends on your use case.

Don't step up to this full-featured, we-could-build-anything system

for the tiniest internal app.

know if you're building a an internal business tool application you don't need a super high

powered authentication system because you're not dealing with that with that kind of level of

clients agreed so yeah good default use use token auth and if you need it jwts are there for you

but there's also and then there's this whole oh well there's so oauth is like where you've got

a server which provides an identity which then you go and authenticate with and there's a behind

the scenes handshake to make sure that you or verification to make sure that you the the token

that you got was correct and then you get an access token which enables the server behind

the scenes to access your identity and this is how social auth works so if you log in with twitter

or log in with facebook or log in with google um or log in with github everyone's seen you know

so-and-so application wants to access your username or your email address without ever

seeing your password yeah that's where you'd use oauth and if and if you use django all auth which

we mentioned previously it makes it very easy to implement social auth via oauth for like 50

different platforms so yeah so for each provider for each platform there's a provider an all auth

provider which you just add as an extra installed app and then it's got the work the flows in place

for you to be able to authenticate with Twitter, say.

Yep, and I have, it's covered in the books,

but I also have a tutorial specifically on Django AllAuth,

which I think I've mentioned before.

So we'll link to that.

People can take a look at how that's done.

But then there's another level, which are these services.

So this is like Autho or Okta,

which you just completely kind of outsource

the authentication piece.

And to be honest,

these are ones where I've read the tutorials.

We'll link to them.

I've heard very prominent people advocate for these, but I don't quite understand why

you would, other than smart people working on big projects are fairly strong advocates

of these.

I don't know, have you been in a case where using one of these services is a better approach

than using the built-in tools?

What's the use case?

The use case for me is if you want to avoid a certain amount of time building stuff around

by django itself so if you you don't need the login templates if you just use ortho or zero

how do you say oh yeah it's probably zero i'm not sure it's zero isn't it because it's zero effort

um but that's the idea but then you kind of lose as well like so it's it's the you in the end you

get jwt logins and you can sort of from a front end app it's very easy to communicate with that

with the Auth0 server and say, yeah, you're logged in.

But then you still need, if you're going to do something in the Django world,

you still need to create a user model in your Django database

that's logged in via this third-party service.

And it's that bit that's always broken down for me.

It's the promise of less work sort of faded away into the air.

It's like, hang on, this is more work.

Yeah, well, that was my experience as well.

It was as much or more work and then a loss of control.

But there's a reason why these services are popular.

And I think I just haven't had the use case myself where it makes sense.

Look, it's again, are you bootstrapping something as a side project or is this your main business?

If this is your main business, then you can't be outsourcing these fundamental parts of it.

But if it's a side project that you're just trying to get knocked out on the weekend, then super, because you get authentication sorted out.

I think we just lost them as potential sponsors, Carlton, but that's okay.

Oh, well, yeah, maybe.

We'll get someone from there to come on and defend this point of view.

Yeah, no, but...

No, I think...

Look, they're useful.

Yeah.

It all depends.

They're useful, but...

It all depends.

And I mean, and that's what we're, you know,

we try in this podcast to not make it a typical engineering,

you know, it all depends.

We're trying to be, to give you our opinions

and argue for them and mention the other side.

Look, if somebody who uses Auth0 wants to come on

and tell me why they use it and why it's great,

I'm happy to listen, I'm happy to learn.

But for me, my experience of trying to implement with them

and trying to work out how I could solve my own use case,

it was just like, no, this is taking my user database

and putting it on someone else's server.

Well, in defense of them, I saw they just in the last couple weeks

have a very nice tutorial on building a Django project

and using Auth0, so we'll link to that.

Yeah, and in fairness, the last time I looked at it

was two years ago, but it's probably quite changed since then.

Yeah. So what else? Anything else to say?

I mean, I think authentication, when I'm teaching beginners, is one of the big parts of Django just because it doesn't just give it to you out of the box.

You're required to configure your signup registration forms, and then if you're building an API, you have to make a choice.

In practice, you use something like Django AllAuth or Django Registration on traditional Django.

If you're doing an API, you use either token auth or JWTs if you need them.

So you quickly become used to that, but it is a hurdle when you're learning Django.

Yeah, and it's just part of the reality of building a web application that you need to handle authentication properly.

So be grateful for what it does do for you.

Be grateful that it doesn't put you in a position where you can blindly shoot yourself in the foot.

You have to make certain choices, but allocate the time.

Don't think, oh, you know, I'll get authentication.

All my authentication problems will be sorted out in 10 minutes.

No, it's an ongoing thing that you need to constantly be looking at and working on.

Keep it as simple as you can, but when you need to step up a level,

you have to allocate the time to step up a level because it's authentication.

And, you know, every week we see stories of sites being broken into

and user data being stolen because they're not secure.

So you have to take it seriously.

And it's, I mean, even, you know, Facebook, well, it's doing lots of things.

But, you know, even Facebook, which has a very strong engineering team, had millions and millions and millions of usernames and passwords being stored in clear text, which I don't even know how, how could you even do that?

I mean, clearly you can, but, you know, Django sort of doesn't let you do that.

Well, it doesn't do database encryption by default, right?

You have to opt into encrypted data, encrypted at store.

So, you know, but passwords are stored encrypted.

Yeah, that's what I'm saying, like the passwords are not stored, even the passwords.

Oh, the passwords were in clean text, oh my word.

Well, I have seen that in many big companies, I thought that was the case with Facebook,

but someone can correct me, but in any case, this stuff is tricky, and even the biggest

companies get it wrong, and what was it, you know, Docker Hub just this week, you know,

someone hacked in, and so, yeah, so if you implement these things properly, if you encrypt

the passwords encrypt your database then even if someone hacks in they can't do as much damage and

django just gives you out of the box the proper way to do it yeah and django does a very good

job at password hashing and um each major version uh with sort of a bump up to the the default

algorithms and bump up the number of iterations of those algorithms for the password hashing

so that's kind of quite secure um well and then there's also you know we were talking before we

started recording so the future of django another you know their add-ons you can do two-factor

authentication which i think there's some effort so that's where you you log in then you have to

confirm like through a text message there's um third-party packages that do this now with django

but i think there's some work to potentially bring that into django itself yeah there's a lot of um

a lot of the core contributors are thinking in this area now and so you know i don't have a

timeline but you know soon enough django will have um you know either one-time passwords or

two-factor authentication built into the core framework as i say there are third-party apps

that enable you to do this already but it would be nice if that was part of core because as we get

further on the the username and password login isn't enough you know most more and more services

are requiring two-factor second factor rules yeah and as the web evolves django evolves with it and

I think actually at the sprints, I know some people were talking about working on just this

very thing at some of the DjangoCon sprints. So that's an example of a number of people talk

online, they do their own things and they come together at a conference and they can

bang out some real progress. Yeah. Anyway. All right. What would I say? Summary, I'd just say,

keep it simple. Allocate the time, but keep it simple. Don't get it more complicated than you

think. Don't build an over-elaborate authentication system until you need it. Yeah. All right.

As always, we are at DjangoChat.com, ChatDjango on Twitter.

And if you have feedback or comments, suggestions for things we should cover, please let us know.

We'll see you next time.

All right. See you next time. Bye-bye.