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 服务器如何准确识别来自同一个用户的两个不同的 http 请求(因为 http 是无连接的)。但我知道这session是使它成为可能的概念。

MIDDLEWARE_CLASSES = ('django.contrib.sessions.middleware.SessionMiddleware',...)在我的settings.py

还有什么我需要检查才能完成这项工作吗?

-编辑

我调试了一下,
django/contrib/auth/ init :login 确实 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 使用给定的 id 查找存储在第 2 步(或在其他情况下)中的数据。
  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

我的第二种看法。

@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 客户端,因此一种选择是调试 Django 中间件以检查 request.COOKIE 的值。如果您在 Django 端没有收到正确的 cookie,则 cookie 在客户端设置不正确。在浏览器上出现这种情况的原因之一是 cookie 可能被禁用。

因此,检查客户端设置以确保正确存储和发送 cookie 是个好主意。

于 2012-11-20T11:26:05.017 回答