0

クライアントはログイン ビューにアクセスします。

//user is properly set here  
user = auth.authenticate(username=email, password=password)  
auth.login(request,user)  

ログイン ビューを要求した同じクライアントが、別のビューを要求します。

// I expect the same user I logged in previously here. But I see anonymous user here.   
user = request.user

Web サーバーが 2 つの異なる http 要求 (http はコネクションレスであるため) が同じユーザーから送信されていることを正確に認識する方法がわかりません。sessionしかし、それがそれを可能にするコンセプトであることは知っています。

私は私MIDDLEWARE_CLASSES = ('django.contrib.sessions.middleware.SessionMiddleware',...)の中に持っていますsettings.py

これを機能させるために確認する必要があるものは他にありますか?

-編集

少しデバッグしましたが、
django/contrib/auth/ init :login do request.session[SESSION_KEY] = user.id django/contrib/auth/ init :get_user は、次の実行時に request.session[SESSION_KEY] を検索しようとして失敗します。

request.session とは何かを理解する必要があります。
リクエストは、クライアントが http-request ごとに送信するものだと思いました(したがって、永続的ではありません)

** 以下は私の理解です。間違っていたら訂正してください **

  1. ユーザーがログインすると、サーバーはユーザーに一意の ID を割り当て、それをユーザーに送信します。
  2. サーバーは、id の関連データも永続的な場所に保存します。
  3. ユーザーは、後続のすべての http 要求に対して一意の ID を送信します (これは Cookie です)。
  4. Django は、ステップ 2 (またはその他の場合) で保存されたデータを、指定された ID で検索します。
  5. Django はデータを request.session に入れ、ビューに渡します。

私はDjangoをフォローしました.request.userは常に匿名ユーザーです

これはすべて、 http://www.micahcarrick.com/django-email-authentication.htmlからコピーしたカスタム認証バックエンドが原因であると思われます

私の最初のビュー。

@csrf_exempt
def login(request):
    # import pdb                                                                                                                                                                                                                                                                
    # pdb.set_trace()                                                                                                                                                                                                                                                           

    email = request.POST['email']
    password = request.POST['password']

    user = auth.authenticate(username=email, password=password)
    # auth.logout(request)                                                                                                                                                                                                                                                      

    if user is not None and user.is_active:
        auth.login(request, user)

        profile = user.get_profile()
        user_dict = profile.to_dict()

        jsonUser = json.dumps(user_dict, ensure_ascii=False, cls=DjangoJSONEncoder)
        return HttpResponse(jsonUser)
    else:
        raise Http404

私の2番目のビュー。

@csrf_exempt
def user_update(request):
    import pdb
    pdb.set_trace()

    user = request.user

=>  if not user.is_authenticated():
        raise Http404  // always ends up here

    print 'in user_update'
.......

MIDDLEWARE_CLASSES = ( 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django. contrib.messages.middleware.MessageMiddleware', # 簡単なクリックジャック保護のために次の行のコメントを外します:
# 'django.middleware.clickjacking.XFrameOptionsMiddleware', )

私のバックエンド

from django.contrib.auth.models import User, check_password

class EmailAuthBackend(object):
    """                                                                                                                                                                                                                                                                         
    Email Authentication Backend                                                                                                                                                                                                                                                

    Allows a user to sign in using an email/password pair rather than                                                                                                                                                                                                           
    a username/password pair.                                                                                                                                                                                                                                                   
    """

    supports_inactive_user = False

    def authenticate(self, username=None, password=None):
        """ Authenticate a user based on email address as the user name. """
        try:
            user = User.objects.get(email=username)
            if user.check_password(password):
                return user
        except User.DoesNotExist:
            return None

    def get_user(self, user_id):
        """ Get a User object from the user_id. """
        print 'getting an user for user_id: ', user_id
        try:
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None
4

1 に答える 1

0

http がステートレスであることについては正しいです。ただし、Cookie を使用すると、リクエストの状態を維持するのに役立ちます。ログイン関数を呼び出すと、Django はユーザー ID (暗号化された値) をsessionidという名前の Cookie に保存します。そのため、次にユーザーからリクエストを受け取ると、ブラウザはリクエスト ヘッダーでこの Cookie も送信します。

*django_session* という名前のテーブルを見ると、 session_key が Cookie sessionidと同じ値を持つエントリが表示されるはずです。

AuthenticationMiddlewareはユーザー認証を追跡し、ユーザー オブジェクトをrequest.userに割り当てます。

SessionMiddlewareは、ユーザーのセッション データを追跡します

これが、Django がユーザーとそのセッションを追跡する方法です。

本当に詳細を調べたい場合は、認証ミドルウェア コード (django.contrib.auth.middleware)、特に process_request を見て、ユーザーがリクエスト オブジェクトにどのように追加されているかを確認してください。

おそらく、これは問題のデバッグに役立ちますか?

編集:

コメントからユージーンを助けたものに基づいています。

セッション関連の問題 (ログインまたはセッション データ) の場合は、クライアント側で Cookie が適切に設定されているかどうかを確認することをお勧めします。デスクトップ ブラウザの場合は、Firebug の [Net] タブにある http ヘッダーを読み取ることで、Firebug のようなツールが役立ちます。

Eugene の場合は Android クライアントなので、1 つのオプションは Django ミドルウェアをデバッグして request.COOKIE の値をチェックすることです。Django 側で正しい Cookie を受信して​​いない場合、クライアント側で Cookie が適切に設定されていません。ブラウザでこれが発生する理由の 1 つは、Cookie が無効になっている可能性があることです。

そのため、クライアント側の設定をチェックして、Cookie が正しく保存および送信されていることを確認することをお勧めします。

于 2012-11-20T11:26:05.017 に答える