I have 2 projects written by Django : 1- Authentication(P1) and 2- my_API(P2). in P1 I use DRF-simplejwt and 'dj-rest-auth' to register,login,logout,reset password ,... for P2 I need authentication. My opinion is that JWT does not use database for checking access token so It does not need to connect my users' db to P2. But now I have error saying that I should migrate auth_user for rest_framework_simplejwt. What should I do now for checking permissions of P2 end points? I also mention that I set both of SECRET_KEYs to the same value. Thanks for your attention :)
The rest_framework_simplejwt plugin uses the User model for authentication and other stuff, even if you don' t perform authentication in the my_API project, you need to migrate the User model (is a requirement). I advice you to create a single project with two applications.
Related
I am building a user module from scratch where users can do pretty much all regular user operations from login,signup,..., to account deactivation. The thing is that I am not using mongoengine or django ready-made models that simplify sql connections, instead I am doing everything from scratch using pymongo driver to connect to mongodb database where I need to code all CRUD operations. I am stuck at creating a temporary link for users to (1) confirm account - this link should not be expired, (2) reset password, this link expires in few days. I have two questions regarding this:
1- can i still use django token generator/ authentication library? I am not using Users django library so my users are just ones I create and insert to database, if yes how can i do that?!
2- if no, how can I generate those temp links considering similar level of security that django library adopts, i.e. hashed username/ salted.. etc.
any advice if I am doing something wrong or I should re-do everything considering mongoengine as my driver so that I can inherit and use django models?! any recommendation is highly appreciated.
Thank you
I would recommend to extend the existing User Model.
Seems easier, faster and more secure than doing everything on your own.
Here is a good source for your options.
https://simpleisbetterthancomplex.com/tutorial/2016/07/22/how-to-extend-django-user-model.html
As the Django documentation says about Other authentication sources, in order to authenticate against another source, you must implement your own authentication backend. Also, They explain that:
The Django admin system is tightly coupled to the Django User object described at the beginning of this document. For now, the best way to deal with this is to create a Django User object for each user that exists for your backend (e.g., in your LDAP directory, your external SQL database, etc.)
As i'm not going to use the admin system (i'm assuming they are referencing the admin application) can i avoid that table replication?
I was thinking of implementing the authenticate and get_user methods as the doc says but that implies the instantiation of the User class, so the next question would be: can the auth.models.User class be instantiated without having the actual Django User table?
The short answer to your question is - yes, it can. Simply set the managed property to False on the User model.
You should map the user from the external authentication into the auth.User object.
Remove django.contrib.auth from the INSTALLED_APPS setting.
Is there a particular reason you don't want the table to be created? If you write (or use a pre-existing) LDAP authentication backend, the User objects will be stored in the table, but they won't have any password information stored, and you can easily update fields like email address and name during the authentication process, so you won't create a disconnect between information stored in LDAP and managed in the Django table (i.e., you can continue updating auth information from LDAP, and don't have to worry about also updating it in the Django DB).
There's no way to avoid the table and still have any sort authentication. The "alternative" authentication methods still make use of the auth_user table, they just authenticate via another means.
I'm new to Django and Mongodb seems really cool and I have a few
questions ! I'm using Django nonrel with Django Mongodb Engine.
I hope I'll not make too many mistakes :)
1 ) Are the Django user authentication system and the Django Session
system working fine ? Because I see on allbuttonspressed.com that
there is a problem with authentication and admin interface and the
part with the 3rd party written authentication backend makes me think
that the django authentication system doesn't work with mongodb :
You can only edit users in the admin interface if you add
"djangotoolbox" to your INSTALLED_APPS. Otherwise you'll get an
exception about an unsupported query which requires JOINs.
Florian Hahn has also written an authentication backend which provides
permission support on non-relational backends. You should use that
backend if you want to use Django's permission system.
2) If the authentication system works fine, how can I add fields to
the user model ? I saw on the Django docs that to achieve that the way
to go is to define a model with a OnetoOnefield to the user model
( "user = models.OneToOneField(User)" ) and define the other fields we
want in that model. I get it that must be the right way with SQL
databases. But with NoSQL like mongodb that just seem wrong to me, if
I'm not mistaken it creates a new collection and puts in each document
an user field used to link the document to the document in the User
collection ( exactly like a foreign key ). That doesn't seem to be a
NoSQL way at all ( Well It's just my feeling but since I'm just a
beginner I may be wrong, don't hesitate to correct me ). Is there a
recommended way to add fields directly to the User model ?
3) When the Model is used in Django, it puts all the fields in the
document even if they are empty right ? Isn't that a waste of space to
write down a lot of fields names in documents if they are empty ?
4) This question is more about Mongodb itself than the engine but I'll
ask it anyway, you may have the answer : How much extra space does it
take to index a field in a collection ?
Didn't think I would have written so much, I hope some of you had the
courage to read me !
Thanks in advance,
Nolhian
Only a partial answer as I don't use MongoDB.
I'm using django-nonrel in a Google AppEngine project. I'm using those other custom apps like "djangotoolbox", and some backends for GAE. Admin panel and standard Django authentication are working very well. I suspect it's the same for MongoDB (like mentioned in the quotation you have provided)
You're right. The standard approach is definitely good for relational databases, but might not work or work inefficiently for NoSQL databases. The typical scenario is to duplicate the data to another table, so you don't have to do JOINs. I think you can simply subclass the User model and add your fields to your custom model (docs).
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.
What would be the best solution to use a different authentication backend for the Django admin site?
See the documentation, which contains this quote:
The Django admin system is tightly
coupled to the Django User object
described at the beginning of this
document. For now, the best way to
deal with this is to create a Django
User object for each user that exists
for your backend (e.g., in your LDAP
directory, your external SQL database,
etc.) You can either write a script to
do this in advance, or your
authenticate method can do it the
first time a user logs in.