首页 文章

django,第一次在网上使用会话

提问于
浏览
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 是使它成为可能的概念 .

settings.py 中有 MIDDLEWARE_CLASSES = ('django.contrib.sessions.middleware.SessionMiddleware',...)

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

-编辑

我调试了一下,
django / contrib / auth / init :login确实是request.session [SESSION_KEY] = user.id django / contrib / auth / init :get_user尝试在下次运行时查找request.session [SESSION_KEY]并失败 .

我需要了解request.session是什么 .
我认为请求是客户端根据http请求发送的内容 . (所以它不是持久的)

以下是我的理解,如果我错了请纠正我

当用户登录时,服务器为用户分配唯一ID并将其发送给用户 . 服务器还在某个持久的地方存储id的相关数据 . 用户为每个后续的http请求发送唯一的id . (这是cookie)Django使用给定的id查找在步骤2(或其他情况)中存储的数据 . Django将数据放入request.session并提供给查看 .

我跟着Django, request.user is always Anonymous 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

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是个好主意 .

相关问题