Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Django users and authentication from external source

I have a Django app that gets it's data completely from an external source (queried via HTTP). That is, I don't have the option for a local database. Session data is stored in the cache (on my development server I use a SQLite database, so that is no error source). I'm using bleeding edge Django 1.1svn.

Enter the problem: I want to use Django's own authentication system for the users.

It seems quite simple to write my own Authentication Backend, but always just under the condition that you have a local database where to save the users. Without database my main problem is persistence.

I tried it with the following (assume that datasource.get() is a function that returns some kind of dict):

class ModelBackend (object):     """Login backend."""      def authenticate (self, username=None, password=None):         """Check, if a given user/password combination is valid"""          data = datasource.get ('login', username, password)         if data and data['ok']:             return MyUser (username=username)         else:             raise TypeError             return None      def get_user (self, username):         """get data about a specific user"""          try:           data = datasource.get ('userdata', username)           if data and data['ok']:               return data.user         except:             pass         return None   class MyUser (User):     """Django user who isn't saved in DB"""      def save (self):         return None 

But the intentionally missing save() method on MyUser seems to break the session storage of a login.

How should MyUser look like without a local database?

like image 620
Boldewyn Avatar asked Jun 29 '09 08:06

Boldewyn


People also ask

How do I authenticate an anonymous user in Django?

Add the above AuthenticationBackendAnonymous middleware into AUTHENTICATION_BACKENDS in your settings.py and use the snippet anonymous_or_real(request) in your views, which returns a user. Comment out the bit where it creates a profile if you are not using profiles.

What is Is_authenticated Django?

For Django 1.10 + As Richard mentioned is_authenticated is a function, so in your view it should be called like: request. user. is_authenticated() . Because of django templating language there can be confusion, because calling this in a template makes it appear as a property and not a method.


1 Answers

OK, it's much more complicated than I thought. First, start with http://docs.djangoproject.com/en/dev/howto/auth-remote-user/, but you'll need to extend it with your own backend and user.

from django.contrib.auth.backends import RemoteUserBackend  class MyRemoteUserBackend (RemoteUserBackend):     # Create a User object if not already in the database?     create_unknown_user = False      def get_user (self, user_id):         user = somehow_create_an_instance_of (MyUser, user_id)         return user      def authenticate (self, **credentials):         check_credentials ()         user = somehow_create_an_instance_of (MyUser, credentials)         return user 

Then the user:

from django.contrib.auth.models import User  class MyUser (User):      def save (self):         """saving to DB disabled"""         pass      objects = None # we cannot really use this w/o local DB      username = ""  # and all the other properties likewise.                    # They're defined as model.CharField or similar,                    # and we can't allow that      def get_group_permissions (self):         """If you don't make your own permissions module,            the default also will use the DB. Throw it away"""         return [] # likewise with the other permission defs      def get_and_delete_messages (self):         """Messages are stored in the DB. Darn!"""         return [] 

Phew! Django really isn't designed for usage without a database...

like image 159
Boldewyn Avatar answered Sep 19 '22 14:09

Boldewyn