I'm trying to figure out how to enhance the authenticate method with additional functionality.
e.g.
Expiring passwords
special password formats
length requirements
etc...
It is pretty straight forward for the site's frontend, but what about the admin panel?
I reckon that I should override the User's Manager object, as authenticate probably resides there. This is quite a tough one to figure out I think.
Thanks in advance! :)
You can create custom authentication backend by following the instructions in http://docs.djangoproject.com/en/dev/topics/auth/#authentication-backends. Essentially, you create a backend class that has an authenticate method:
class MyBackend:
def authenticate(self, username=None, password=None):
# Check the username/password and return a User.
Then add the class to AUTHENTICATION_BACKENDS in settings.py.
Though this is for authentication, you could do all the password validation things you mentioned simply by redirecting a user to a change password page if the password is correct but expired, for instance. Consider using the messaging framework to give a user a hint about what is going on when directing him to a generic change password page.
If you want the validation for passwords to be built into the model, then you'll probably want to extend the django User model.
Otherwise, you could do the following:
override admin password options by creating your own views for changing and setting passwords, then putting the relevant URLS just above (r'^admin/', include(admin.site.urls)). Regex would look something like (r'^admin/auth/user/(\d+)/password/', new_change_password).
Keep track of password age in a separate model and then when they expire, redirect to a change password once it expires.
Related
Is there a way to set up the django authentication model where, instead of a password, users put in their email address, and then are emailed a link that they click on to login with? If so, are there any tutorials on how to set this up?
Yes, there is.
You'll either need to hope there is already a module out for this, otherwise you will have to write your own way of authenticating.
I'll give a rough estimate of how it's gonna work.
First, you will need to create a class inheriting from AbstractBaseUser
Set the username field to email, still include password fields. They are required.
Then, you will need to create a manager for that custom base user.
the user manager must have two methods: create_user() and create_superuser()
Then, in a view, have user enter their email address, and then generate a token with Django's default_token_generator, and send that token via e-mail to the user.
Create a view which accepts the token, and logs the user in.
I highly advise you to take the docs as your guide. This might get relatively complicated.
More info on the Django Docs
Side note: This will not be as secure as email and password validation. If a user's email gets hacked, the hackers will instantly know not only which site they can target, but also get a free pass to access.
Alternatively; check out Django AllAuth, they provide lots of ways to authenticate, including with Gmail or Facebook. There are some great tutorials online, but you'll have to do some googling. ;)
Hey guys so basically I’m implementing a custom user model extending from AbstractUser. I am also using Allauth.
In previous practice projects I have built I am able to configure Allauth so that I can register new users and login in with only an email and password. This however is implemented without actually extending my user model(I just created the class and the passed). When I do then add custom fields for my users with my current project, and after reading the docs for Allauth about custom user models, I loose that functionality. I have to login with a username.
What I would like is to have my login how it works when you don’t extend the user model. Meaning that you can register and login in with you email and password. I have tried all the combinations I can think of using the settings in Allauth docs. I just cant seem to figure it out. Has anyone had a similar experience or just know perhaps what im doing wrong?
I am working on a project where I need to have 3 types of Users.
Admin
Vendor
Customer
I want to be having seperate Models for all three of them Vendor & Customers instead of having a type field in a common User Model.
My first approach to this problem was to define all models by sub-classing the AbstractUser model
# models.py
from django.contrib.auth.models import AbstractUser
class Customer(AbstractUser):
pass
class Vendor(AbstractUser):
pass
And add a custom Authentication backend to handle the authentication of users based on the request object.
# settings.py
AUTHENTICATION_BACKENDS = ['backends.CustomAuthBackend']
And my backends.py file will contain the logic to authenticate users and use different models for each one based on the request object.
# backends.py
from __future__ import print_function
class CustomAuthBackend(object):
def authenticate(self, request, username=None, password=None):
# authenticate user based on request object
def get_user(self, user_id):
# logic to get user
However this does not work and looks like i also need to specifiy the AUTH_USER_MODEL in settings.py which is used for authentication.
Is it possible at all.Does Django allow to authenticate from 3 different tables. How can I go ahead with this ? Is there any other approach to this and what should I change ?
I have done similar staff a couple days ago, you are in the right approach. But there are a few other things needed to change to make it work. I'll explain what I did to make it success.
First, you have to custom your own user model, and you have to do it in the first place before you make the migrations. And also in the model file define different userManagers to manager different type of users. Then in your settings file you have to set AUTH_USER_MODEL and AUTHENTICATION_BACKENDS, AUTH_USER_MODEL is the default user model django will use for authentication and you can only set to one user model, but for AUTHENTICATION_BACKENDS you can have multiple backends,it's a list and django will loop every option inside to authenticate. by default it use django.contrib.auth.backends.ModelBackend, you can add your own auth backends. Check this on how to make your own authentication backend:https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#writing-an-authentication-backend.
And depends on your application, you may also need to custom the serializer function and override some classes to make it work. In my own application, I was using DRF and JWT token to authenticate, so I also override some of the function which by default use the AUTH_USER_MODEL variable. In the end, I'm able to use admin model to login the admin page and use another custom user model to authenticate the application and get the JWT token. Anyway, always reference this page: https://docs.djangoproject.com/en/1.11/topics/auth/customizing/#customizing-authentication-in-django. Hope this can help you in your application.
django.contrib.auth is designed to work with one UserModel. Depending on what you want to achieve there are different apporaches.
If you just want to store different kind of profile/meta data for the different types of user you might use multi table inheritance - in this case you might stick with the default user model.
When it comes to different permissions based on the user type you should not solve this using separate classes. Instead use groups. This approach is much more flexible. It can nearly always happen that one person should belong to more than one group of users. When you model this based on the user classes you are in trouble.
I'm using django 1.9.7 and django-allauth to handle my user authentication.
I have a contact form that includes several Fields (including the users email address) which are saved as a model in the backend, from there I am using a ModelForm to display the fields. So far so good.
Now there should be a checkbox, which when checked should add two fields (password, password confirm) and instantly create an account with the email and password provided.
For this I would probably manually create a user object from the view that receives the contact information, but since its security relevant I'm wondering if there is an easy way to call a allauth method from python that creates the user (or even provides the form).
How would I go about this?
Update: So i found the adapter has a method called save_user() which would populate the information and save the new user.I could then add the two password fields to the form and just pass the form in there.
My issue that it would skip all the username and password cleaning, the email confirmation or the auto login after sign up.
You should be able to use the new_user() method in the default adapter. refer here https://github.com/pennersr/django-allauth/blob/master/allauth/socialaccount/adapter.py
I would like to force the user to change their password on first login. Can I do this with the default django authentication system?
In short, yes.
You need to know which users need to change their password. If you don't want to use a custom User model, I would recommend having another model to store the users that need to change their password. You would add the users to this table upon user registration/creation.
Then you could write a very simple middleware to check the current logged user (place it after AuthenticationMiddleware in your settings.py). If the user is flagged as requiring a password change, you could force a HttpResponse (in the middleware) to a custom view with a PasswordChangeForm (which comes out of the box in Django, in django.contrib.auth.forms.PasswordChangeForm), after which you could remove the flag to the user, and redirect them to the home page.