2011-08-05 5 views
0

最新のDjangoプロジェクトに既存のデータベースを使用していますので、モデルやDjango認証コードを変更しない限り、 。Python/Djangoでauthとセッションがどのように機能するか少し混乱します

既存の認証バックエンドを使いこなすのではなく、自分の認証アプリを作成するだけです。

私の以前の認証アプリはすべてPHPで書かれていますが、基本的にはセッション変数のすべてをスローしてすべてのページで確認しています...ここで私はちょっと混乱しています。ユーザーが認証/ログインすると、ユーザー全体がセッションに追加されるように見えますが、どこで発生しているのか把握できません。

デフォルトのDjangoログイン機能では、ユーザーをrequest.userに割り当てています...これは何とかセッション変数として保存されているのですか、それとも次のビューに渡されただけですか?それが次のビューに渡されているだけであれば、それ以上のログイン要求を必要とせずに将来の要求はどのように認証されますか?

Djangoの認証ログインは以下の通りです。..デフォルト

def login(request, user): 
    """ 
    Persist a user id and a backend in the request. This way a user doesn't 
    have to reauthenticate on every request. 
    """ 
    if user is None: 
     user = request.user 
    # TODO: It would be nice to support different login methods, like signed cookies. 
    if SESSION_KEY in request.session: 
     if request.session[SESSION_KEY] != user.id: 
      # To avoid reusing another user's session, create a new, empty 
      # session if the existing session corresponds to a different 
      # authenticated user. 
      request.session.flush() 
    else: 
     request.session.cycle_key() 
    request.session[SESSION_KEY] = user.id 
    request.session[BACKEND_SESSION_KEY] = user.backend 
    if hasattr(request, 'user'): 
     request.user = user 
    user_logged_in.send(sender=user.__class__, request=request, user=user) 

私はまた、)(user_logged_in.sendを追跡しようとしたdjango.dispatch.dispatcher.sendであるが、私は何を全くわからないんだけどそれはどちらかを行うことになっています。

def send(self, sender, **named): 
    """ 
    Send signal from sender to all connected receivers. 

    If any receiver raises an error, the error propagates back through send, 
    terminating the dispatch loop, so it is quite possible to not have all 
    receivers called if a raises an error. 

    Arguments: 

     sender 
      The sender of the signal Either a specific object or None. 

     named 
      Named arguments which will be passed to receivers. 

    Returns a list of tuple pairs [(receiver, response), ... ]. 
    """ 
    responses = [] 
    if not self.receivers: 
     return responses 

    for receiver in self._live_receivers(_make_id(sender)): 
     response = receiver(signal=self, sender=sender, **named) 
     responses.append((receiver, response)) 
    return responses 

基本的に私が探しているDjangoフレームワークに依存しないPythonでユーザーセッションデータを保存するための効率的な方法を説明するために誰かのためです。 Django認証のやりとりは少しうまくいくでしょう。

答えて

9

HTTPはステートレスです。使用されるサーバー、フレームワーク、言語にかかわらず、HTTPクライアントが「この要求はそのセッションの一部です」という本質的な方法はありません。それはHTTPの設計の一部です。

セッションは常にWebアプリケーションの機能です。ウェブアプリケーションフレームワークでサポートされているか、アプリ自体に実装されています。ステートフルなセッションがステートレスなプロトコルから作成される最も一般的な方法は、Cookieです。クライアントは、サーバーの要求に応じてクッキーを保存し、将来の要求でそのクッキーをそのサーバーに戻します。

セッションデータをシリアル化してクッキー自体に格納することはできますが、秘密情報(秘密情報は偽造または盗聴される可能性があります)と非効率的(個々のバイトがクライアントにとって役に立たなくても帯域幅を消費します)したがって、好ましい解決策は、不透明(かつより良い単一使用)セッションキーを使用することであり、クッキーに格納され、ウェブアプリケーションはセッションデータを帯域外に格納する。メモリ、ファイルシステム、データベースのバックエンド、またはその他のオプションのいずれかを使用します。

djangoは、着信要求と発信応答を変更するモジュールである "ミドルウェア"において、これを透過的に処理します。 authミドルウェアはCookieを読み取り、それがログインしているユーザを表しているかどうかを確認し、そうであればリクエストにユーザオブジェクトを追加します。セッションミドルウェアは、同様の方法で動作し、クッキーをチェックし、リクエスト間に保存されていたどこからでもセッションデータを読み込み、レスポンスからセッションデータを取得して保存しますクッキーを設定して、クライアントのセッションと保存したばかりのセッションデータを関連付けます。

これらの機能は両方とも互いに独立しているため(セッションを回避する傾向がありますが、通常はある種の認証を使用する傾向があります)、相互に依存しません。セッションライクな認証はセッションと同様の方法で実装されますが、認証されたユーザは「セッション」に格納されず、セッションは「認証されたユーザ」に接続されません。

そうは思わないかもしれませんが、djangoの認証システムはdesigned to be extendedです。あなたが認証したい正当なユーザのデータベースをすでに持っているなら、標準のdjango認証アプリケーションにうまく収まる新しい認証バックエンドを追加するのは非常に簡単です(つまり、それに依存する他のアプリケーションを順番に使うこともできます)。

関連する問題