built-in django.contrib.auth.models.User VS own User model? - django

I'm writing a web app using the django framework and I was just wondering what are the pros/cons of using the built-in django.contrib.auth.models.User model over my own user model?
Please explain in terms of performance, scalability and security.
Many thanks

I always use the contrib.auth.models.User model, as many other apps also use it. Even if you want to have differences, it usually ends up being simpler to extend using a UserProfile than to try to build your own.

Unless you need to integrate with an auth backend that doesn't reasonably fit with contrib.auth, there aren't really any reasons to roll your own authentication app. auth provides its own access control models, but if they don't match your needs you don't need to use them. it provides a number of auth backends but if none of them are quite an exact match, then you can write your own backend and still use the rest of contrib.auth

Related

REST API with Django Admin

I am building an API-first app with the Django REST framework, so it has no html views at all and uses only token-based authentication. At the same time, I would like to make use of the Django admin interface, which is no problem, but I am worried about the performance costs as it depends on a lot of apps (sessions, standard auth, messages, csrf, etc.), that are not needed in the main app, but will run on every request.
Is there a way to set admin-specific middlewares to run only on the admin interface?
I know I can subclass them and raise MiddlewareNotUsed on all requests except ones going to the admin site, but maybe there is some build-in or well-known solution to this?
To answer your question, no, I don't think there are built-in solutions that cater to this. But that's probably because your purpose is not a good fit for Django's design and philosophy.
I'm with the comment by Sahil on this. I used to be paranoid about performance too, but I realized that I was underestimating Django's speed (even with all these basic middleware), and that if performance was that critical, I probably shouldn't be using Django in the first place. I'm guessing that disabling these middleware will save an app's response time only unnoticeable milliseconds at most; inevitable network fluctuations might even be more significant. A developer's time is more expensive than the additional hardware that could be thrown at any performance and/or scalability problems that come up.
But if you still want to save on the middleware processing, I have an alternative idea: the convenience functionality provided by the Django admin (that is, CRUD operations) could be replicated quite rapidly with DRF viewsets. Perhaps you could build a corresponding API client using some rapid-development frontend framework for your users. (I was going to say, just use the DRF browsable API, but I remembered that also relies on pretty much the same basic middleware as the Django admin.)

Should I split my Django and DRF project into separate projects?

I am currently at the planning stage of an app that will consist of standard
Django part for supervisors that can perform all CRUD operations on employee users mostly add, delete and view statistics - viewed in browser (no frontend framework just using Djangos server side rendering), two step email authentication on each login, session based auth
DRF part for employees - API connected to mobile app, authentication based on device ID. (no username, or password)
DRF part for clients to contact the supervisors if employees do something wrong - Token or JWT based authentication using passcode delivered by mail.
I am not used to splitting Django projects into multiple sub-projects (or using same database for different projects) but it feels like every part of the project should be a standalone app due to different authentication type and the fact of simultaniousily using DRF with standard Django
Can anyone who had similar problem or has some experience, advise what should I do considering different authentications and overall different user types in this project? What would be pros and cons of going into solo or multiple projects? Thanks in advance!
You're asking for opinions, so don't be surprised if the question gets closed, but I'll answer with facts:
A split over different projects using the same database has the following issue: shared migrations. They all use built-in users, so require some standard apps to be enabled that have migrations and they won't run on the 2nd and 3rd project.
You're going to need a custom user model to support the device id authentication method: You need information that is not on the standard user model to be available at authentication time - the number 1 reason to create a custom user model. Ties into migrations and also a synchronization hell code-wise.
Django's Authentication Backends system allows for different authentication methods to exist at the same time, so there is no need to split anything. If you're worried about security, you can always use different hostnames and the Sites framework to add an extra layer of protection, but they would still use the same code.
DRF started as an addition to Django's view-based approach, not a replacement to make part of a project's code available as an API. While current usage is more "DRF or templates" this is a result of people increasingly becoming binary ("this" or "that") and wanting to be in the cool club, but has nothing to do with technical reasons. They can and always will be able to co-exist as they solve different problems. In fact, DRF's generic views make use of Django's CBV's and the built-in browsable API makes use of templates. Also, the admin is template/view based and it's convenient to develop the app or manage data with the built-in admin.

Django : looking for an implementation of an ldap db backend (or for any help on this)

Following this post (I was looking for a library allowing me to declare Django models on a ldap backend), I have decided to use ldapdb. After having played a while with this library, I figured out that it doesn't reach the level of control I need, and I am therefore looking for other solutions. What I am thinking of now is implementing a Django db backend based on python-ldap.
EDIT
I need this because I am currently implementing a user/group management system on a ldap directory (it requires to be able to manipulate not only users, but different classes of ldap objects as well). So basically, I would like to be able to use (nearly) full Django orm, but with a ldap backend.
Because I love Django (and would be rather motivated in learning the dirty low-level details of db.backends), and because there's already a lot of things implemented in this project, I would like to stick to Django (unless somebody has a very good reason why I shouldn't, and a very good alternative !).
Do some of you have a simpler solution to this problem ?
Do some of you know about an implementation of such a thing (ldap db backend) ?
Do some of you know some good reads to get started on "implementing a Django db backend"?
Are some of you interested in helping with this project ?
You make a lot of bold statements such as "lots of things broken because of the way it is implemented" and "the subclassing is very very far from being complete", would you care to elaborate on them? As the author of django-ldapdb I would welcome your suggestions as to what you would like changed/fixed, that's what the django-ldapdb mailing list is for!
FYI, I took the approach of subclassing the Model class because you will usually want to have just a couple of models using the LDAP backend, not all the models in your application, and django 1.1 did not support multiple databases. Also, LDAP is very different from existing SQL backends:
is not a relational database
it is not "flat", it is a tree-like
the true "primary key" for an entry is the Distinguished Name (DN), which is not an actual field, but a value computed from other fields
fields can be multi-valued
For all these reasons, I have serious doubts as to what can be achieved by writing a true LDAP backend. I think you will always have some LDAP-specific quirks, and subclassing Model allows just that.
Your best bet is probably to write an authentication backend for the application. Here is some documentation about it:
http://docs.djangoproject.com/en/dev/topics/auth/?from=olddocs#writing-an-authentication-backend
And here is an article that explains how to extend the User model to enable you to use this authentication backend seamlessly:
http://scottbarnham.com/blog/2008/08/21/extending-the-django-user-model-with-inheritance/
Seems like there's no really good solution. And doing everything without Django's ORM is no good solution either.
I'll make new attempt at solving that problem soon, with a django-orm-based solution.

Django and Common Access Cards (CAC)

A web app written in Python is planned, Django is a leading contender as framework.
One requirement is CAC access, wihout the need to hand enter username and password. From what I can tell, CAC access is not part of the "batteries" included with Django.
As a monolithic framework (not necessarily a bad attribute) Django has a rep for being high-maintenance once you modify the core. Can I easily add CAC access to a Django site? Can it be easily maintained thereafter?
Or maybe we should consider a different Python framework?
FYI.. interesting presentation on CAC access link
You don't need to modify the core to enable this. Django supports third-party authentication backends and they're fairly easy to write - you just need to support two methods, get_user and authenticate. So your implementation just needs to perform these operations using your CAC interface, and all will work as usual.
See the documentation for details.
Edited after other answers I don't know why people are saying this is difficult in Django. Yes, many parts of Django are difficult to customise. But this is one particular part that is made very easy. I've written several authentication backends in Django and they are not only really simple, but they "just work" with the rest of the framework, including the admin. There isn't any need to modify anything else to get this to work.
I just did this today by subclassing django.contrib.auth.middleware.RemoteUserMiddleware and changed the header property to the one I had set in my apache conf. I just added the django.contrib.auth.backends.RemoteUserBackend and my middleware to the settings and it works perfectly.
Extending contrib.auth is a pain in the neck. It's the single worst thing in django. If you need highly customized auth backend, i would suggest using a different framework.

Alternative Django Authenication

Need to integrate Django with an existing authentication system. That system has it's own database, API, login/logout,edit profile web pages and cookie.
(I may have to add a few additional profile fields stored/updated locally)
What's the proper approach to substitute the out-of-the-box authentication in Django?
The proper approach to substitute authentication from django's out-of-the-box to your own is to substitute your classes in the AUTHENTICATION_BACKENDS tuple in settings.py as described in http://docs.djangoproject.com/en/dev/topics/auth/#specifying-authentication-backends. This is incredibly useful for just the issue you're describing.
A good example of an authentication backend done this way is django-cas. This uses CAS to authenticate in a django application. You can use this as your template and just write hooks into your own authentication system identically.
HTH
I've created a custom authentication backend when I've had to do something similar to what you have to do. See: http://docs.djangoproject.com/en/dev/topics/auth/#writing-an-authentication-backend
In the authenticate function you call your api to authenticate the user, and then map them to a django.contrib.auth.model.User object on some primary key, like username for example. If the primary key is something other than username I usually create a mapping object, or put it into the profile object for the project.
This depends on how you want to handle the problem. If you don't need to keep the existing system running, your best bet is to import their data into the django project.
If the authentication system must stay in tact, you might have to write a wrapper for django.auth. I've done this in the past using SQLAlchemy http://www.sqlalchemy.org to integrate to the external database.
It might be helpful to take a look at the Django 1.2 multi-db support http://djangoadvent.com/1.2/multiple-database-support
In either case I'd try to get the user information into django.auth rather than to write your own authentication system.