客户端访问登录视图,
//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 回答
你是对的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是个好主意 .