2009-06-29 24 views
16

Verilerini tamamen harici bir kaynaktan alan (HTTP aracılığıyla sorgulanan) bir Django uygulamasına sahibim. Yani, yerel bir veritabanı için seçeneğim yok. Oturum verileri önbellekte saklanır (geliştirme sunucumda bir SQLite veritabanı kullanıyorum, bu yüzden herhangi bir hata kaynağı yok). Ben kanama kenarı Django 1.1svn kullanıyorum.Django kullanıcıları ve dış kaynaktan kimlik doğrulama

Sorun girin: Kullanıcılar için Django'nun kendi kimlik doğrulama sistemini kullanmak istiyorum.

Kendi Kimlik Doğrulama Geri Bildirimi yazmak oldukça basit görünüyor, ancak her zaman, kullanıcıları kaydetmek için yerel bir veritabanınızın olması şartıyla. Veritabanı olmadan benim temel sorun sebat.

I ( datasource.get() dict çeşit döndüren bir fonksiyon olduğunu varsayalım) Aşağıdaki ile denedim:

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 

Ama MyUser üzerinde kasıtlı eksik save() yöntem oturum açma oturum depolamasını kırmak gibi görünüyor.

Yerel veritabanı olmadan nasıl MyUser nasıl görünmeli?

+4

istediğimi yapmama gibi görünüyor. Eğer değerlendirmiş olsaydım, bir cevap gönderirim (kendi eklemek için cesaret kırmayın ;-)). – Boldewyn

+0

Bağlantı bozuk bir şekilde devam ediyor '>' ... darn. – Boldewyn

cevap

22

Tamam, düşündüğümden çok daha karmaşık. İlk olarak, http://docs.djangoproject.com/en/dev/howto/auth-remote-user/ ile başlayın, ancak kendi arka uç ve kullanıcı ile genişletmeniz gerekir.

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 

Ardından kullanıcı:

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 [] 

Sonunda! Django gerçektensave yöntemi üzerine yazmak yerine daha ziyade ... bir veritabanı olmadan kullanım için

+1

Ayarlar dosyanızda neyi değiştirmek zorunda kaldınız? Bunu yapmaya çalışıyorum ve uzaktan arka uçumu tamamen görmezden geliyorum. – Colleen

+1

"AUTHENTICATION_BACKENDS = ( 'myapp.MyappUserBackend', )' ile ilgili bir şey ayarladınız mı? – Boldewyn

+0

Evet.Anladığım kadarıyla, uzaktaki ortadaki ara katman yazılımını benim durumumda genişletmem gerekiyordu çünkü kimlik bilgilerini varsayılandan farklı olarak geçiyordum. – Colleen

1

grep ping kaynağı tek yer user.save() aslında user.last_login değerini güncellemek için, django.contrib.auth.login() olan (sen hiç kullanmak gerekmez kullanıcı oluşturma ve şifre yönetimi kodu hariç) olduğunu söyledi gösterdi.

# TODO: It would be nice to support different login methods, like signed cookies. 
user.last_login = datetime.datetime.now() 
user.save() 

Eğer kullanıcı verileri, DB dinlenme kukla save() yöntemi ekleme denemek istemiyorsanız

. Haklıysam işe yaramalı. Hiç mi süreğenliğinde, çünkü Caching datasource.get sonuçları dikkate almalıdır Tabii

def save(self, *args, **kwargs): 
    pass 

, aksi kötü durumda kullanıcının hit oturum her üzerine tekrar tekrar veri sorgulama sona erebilir.

4

tasarlanmamıştır, ayrıca bunu çağırır sinyali kesebilir. Bu, kullanıcı veritabanına salt okunur erişimi olan bazı uygulamalarda yaptığım şeydir. Sadece bulundu

# models.py (for instance) 
from django.contrib.auth.models import update_last_login, user_logged_in 
user_logged_in.disconnect(update_last_login) 
+0

Django 1.6 ve OP + ile çalışıyorum, bu günümü kurtardı! Teşekkür ederim! – enpenax

İlgili konular