可以将文章内容翻译成中文,广告屏蔽插件可能会导致该功能失效(如失效,请关闭广告屏蔽插件后再试):
问题:
I am using a custom authentication backend for Django (which runs off couchdb). I have a custom user model.
As part of the login, I am doing a request.user = user
and saving the user id in session. However, on subsequent requests I are not able to retrieve the request.user. It is always an AnonymousUser. I can however retrieve the user id from the session and can confirm that the session cookie is being set correctly.
What am I missing?
I do not want to use a relational db as I want to maintain all my user data in couchdb.
Edit: I have written a class which does not inherit from Django's auth User. It however has the username and email attributes. For this reason, my backend does not return a class which derives from auth User.
回答1:
Please elaborate. If you are using a custom user model (which is different from a custom user PROFILE model), then you are basically on your own and the django.contrib.auth framework can not help you with authentication. If you are writing your own authentication system and are not using django.contrib.auth, then you need to turn that off because it seem to be interfering with your system.
回答2:
The request.user
is set by the django.contrib.auth.middleware.AuthenticationMiddleware
.
Check django/contrib/auth/middleware.py
:
class LazyUser(object): def __get__(self, request, obj_type=None): if not hasattr(request, '_cached_user'): from django.contrib.auth import get_user request._cached_user = get_user(request) return request._cached_user class AuthenticationMiddleware(object): def process_request(self, request): request.__class__.user = LazyUser() return None
Then look at the get_user
function in django/contrib/auth/__init__.py
:
def get_user(request): from django.contrib.auth.models import AnonymousUser try: user_id = request.session[SESSION_KEY] backend_path = request.session[BACKEND_SESSION_KEY] backend = load_backend(backend_path) user = backend.get_user(user_id) or AnonymousUser() except KeyError: user = AnonymousUser() return user
Your backend will need to implement the get_user
function.
回答3:
You say you've written a custom authentication backend, but in fact what you seem to have written is a complete custom authentication app, which doesn't interface with Django's contrib.auth
.
If you want to use a non-relational database for your authentication data, all you need to do is create a class that provides two methods: get_user(user_id)
and authenticate(**credentials)
. See the documentation. Once you have authenticated a user, you simply call Django's normal login methods. There should be no reason to manually set request.user
or put anything into the session.
Update after edit That has nothing to do with it. There's no requirement that the user class derives from auth.models.User
. You still just need to define a get_user
method that will return an instance of your user class.
回答4:
I too have custom authentication backend and always got AnonymousUser
after successful authentication and login. I had the get_user
method in my backend. What I was missing was that get_user
must get the user by pk
only, not by email or whatever your credentials in authenticate
are:
class AccountAuthBackend(object): @staticmethod def authenticate(email=None, password=None): try: user = User.objects.get(email=email) if user.check_password(password): return user except User.DoesNotExist: return None @staticmethod def get_user(id_): try: return User.objects.get(pk=id_) #
Its easy to miss this line in the docs:
It so happened that email
is not primary key in my schema. Hope this saves somebody some time.