问题
I use custom User
, and I have an email_verified
field for this user.
I'd like when a user sign in, to be rejected if this field is false
.
I can't do it in views.py
since users can sign in from various sources (Django site but REST APIs too).
The whole purpose is to avoid to write N times the logic for N sign in sources. I'd like to override a method (login()
? authenticate()
?) in models.py to do that only once.
I quickly read the doc about customizing authentication but did'nt find what I'm looking for.
Thanks for help.
回答1:
Please refer to Django Doc: Writing an authentication backend, it's probably what you're after. It covers both your use case on normal login and REST APIs like token authentication:
The authenticate method takes credentials as keyword arguments. Most of the time, it’ll just look like this: class MyBackend(object): def authenticate(self, username=None, password=None): # Check the username/password and return a User. ... But it could also authenticate a token, like so: class MyBackend(object): def authenticate(self, token=None): # Check the token and return a User. ... Either way, authenticate should check the credentials it gets, and it should return a User object that matches those credentials, if the credentials are valid. If they’re not valid, it should return None.
Once you have written your custom auth backend, you just need to change your default auth backend in your settings.py
like this:
AUTHENTICATION_BACKENDS = ('project.path.to.MyBackend',)
Update
Rather than overriding the default authenticate
behaviour, you can just include both Backends in your settings, like:
AUTHENTICATION_BACKENDS = ('project.path.to.MyBackend',
'django.contrib.auth.backends.ModelBackend',)
The order of the Backends matters, you can read the source code and have a better understanding how the default authenticate
and things work together (Read here)
AFAIK this is the preferred way to customise authenticate
, as you may one day change your default Backend to something like RemoteUserBackend or whatever (like from RestFramework) and so you can just place your logic (MyBackend) by order in your settings and no need to worry about breaking the code.
Hope this helps.
来源:https://stackoverflow.com/questions/27681987/django-how-to-override-authenticate-method