2009-06-29 23 views
16

私は外部ソースから完全にデータを取得するDjangoアプリを持っています(HTTP経由で照会)。つまり、私はローカルデータベースのオプションを持っていません。セッションデータはキャッシュに保存されます(私の開発サーバーではSQLiteデータベースを使用しているため、エラーソースはありません)。私は出血エッジDjango 1.1svnを使用しています。Djangoユーザーと外部ソースからの認証

問題を入力してください:ユーザーにDjango独自の認証システムを使用します。

自分の認証バックエンドを作成するのは簡単ですが、ユーザーを保存するローカルデータベースがあるという条件の下では常にそうです。データベースがなければ私の主な問題は永続性です。

私は(datasource.get()は辞書のいくつかの種類を返す関数であると仮定)次でそれを試してみました:

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 

しかしMyUserとの意図的に欠落しているsave()方法は、ログインのセッションストレージを破るようです。

MyUserはローカルデータベースなしでどのように見えるのですか?

+4

は私がやりたいようです。私が評価したら、私は答えを投稿します(あなた自身を追加することをお勧めしません;-))。 – Boldewyn

+0

リンクには、「>」というダンがあります。 – Boldewyn

答えて

22

OK、それは私が思ったよりずっと複雑です。まず、http://docs.djangoproject.com/en/dev/howto/auth-remote-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 

次にユーザー:

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

ふう!ジャンゴ本当に

+1

設定ファイルで何を変更する必要がありましたか?私はこれをしようとしている、それは私のリモートバックエンドを完全に無視しているようだ。 – Colleen

+1

AUTHENTICATION_BACKENDS =( 'myapp.MyappUserBackend'、 ) 'に沿って何かを設定しましたか? – Boldewyn

+0

はい。私はそれを理解しました、私はデフォルトのものとは異なる資格情報を渡していたので、私のケースではリモート認証ミドルウェアを拡張する必要がありました。 – Colleen

1

grep pingがソースが唯一の場所user.save()が実際にuser.last_login値を更新するために、django.contrib.auth.login()がある(あなたがすべてで使用する必要はありません、ユーザーの作成およびパスワードの管理コードを除く)と呼ばれていることを示しました。

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

あなたはユーザーデータをDBに休息したくない場合は、ダミーsave()メソッドを追加してみてください。もし私が正しいなら、それはうまくいくはずです。もちろん

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

あなたは全く持続性を持っていないので、あなたはdatasource.get結果をキャッシュ考慮しなければならない、そうでない場合は、最悪の場合には、ユーザーのヒットですべての単一のログに記録された上で何度もデータを照会することに終わる可能性があります。

4

よりもむしろsaveメソッドを上書きし...データベースなしでの使用のために設計されていない、あなたもそれを呼び出し信号を切断されることがあります。これは、ユーザーデータベースへの読み取り専用アクセスを持ついくつかのアプリで私がやっていることです。私はちょうど見つけ

# 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と一緒に作業しています。ありがとうございました! – enpenax

関連する問題