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

时间:2012-11-20 10:35:48

标签: android django session login

客户端访问登录视图

//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

我需要检查一些其他功能吗?

-edit

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

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

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

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

我关注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 :(得分:0)

http是无国籍的你是正确的。但是,使用cookie可以帮助您维护请求的状态。当您调用 login 函数时,Django会将用户ID(加密值)保存在名为 sessionid 的cookie中。因此,下次您收到用户的请求时,浏览器也会在请求标头中发送此cookie。

如果查看名为* django_session *的表,您应该看到一个条目,其中session_key与cookie sessionid 具有相同的值。

AuthenticationMiddleware 跟踪用户身份验证并将用户对象分配给 request.user

SessionMiddleware 跟踪用户的会话数据

这就是Django将如何跟踪用户及其会话。

如果您真的想查看详细信息,可以查看身份验证中间件代码(django.contrib.auth.middleware),尤其是process_request,以检查用户在请求对象中的添加方式。

也许这在调试问题时很有用?

编辑:

基于什么帮助Eugene发表评论。

当它与会话相关的问题(登录或会话数据)时,最好检查cookie是否在客户端正确设置。如果它是桌面浏览器,通过阅读Firebug的“Net”选项卡中的http标头,Firebug之类的工具会很有帮助。

在Eugene的情况下,它是一个Android客户端,因此一个选项是调试Django中间件来检查request.COOKIE的值。如果您没有在Django端收到正确的cookie,那么在客户端没有正确设置cookie。其中一个原因是浏览器可以禁用cookie。

因此,最好检查客户端设置,以确保正确存储和发送Cookie。