我按照django doc的建议实现了一个自定义身份验证后端我有两种方法 - authenticate和get_user .

我确认我的自定义'authenticate'方法被调用并返回一个正确的用户但是在request.user中我总是得到AnonymousUser并且我的“get_user”方法永远不会被调用 .

它可能是会话的东西,因为当我解码我的会话时,我唯一看到的是 "{u'django_language': u'en'}"

我错过了什么?

这是我的自定义SSOBackend

class SSOBackend(object):
    """
    My authentication backend
    """

    def authenticate(self, *args, **kwargs):
        """
        Authenticate user using access_token and refresh_token
        """

        access_token = kwargs.get('access_token')
        refresh_token = kwargs.get('refresh_token')
        user_info = _get_user_info(access_token, refresh_token)
        try:
            user = User.objects.get(username=user_info['user_id'])
        except User.DoesNotExist:
            import uuid
            random_password = uuid.uuid4()
            user = User(username=user_info['user_id'], password=random_password)
            user.save()

        return user


    # Required for your backend to work properly - unchanged in most scenarios
    def get_user(self, user_id):
        try:
            logger.info("SSOBackend.get_user:  User_id = %s" %user_id)
            return User.objects.get(pk=user_id)
        except User.DoesNotExist:
            return None

我正在使用我的自定义中间件登录用户:

class SSOMiddleware(object):

    def process_view(self, request, view_func, view_args, view_kwargs):

        if 'state' in request.GET and 'code' in request.GET and '/auth-callback/' in request.get_full_path():

            redirect_uri = "http://{domain}/sso/auth-callback/".format(domain=request.get_host())
            next_page = "/"


            code = request.GET['code']

            # where to redirect after successful authentication
            next_page = request.GET['state']

            config = SSOConfig()
            token_url = config.token_url
            client_id = config.client_id
            client_secret = config.client_secret

            # retrieve access token using code
            headers = {"content-type": "application/x-www-form-urlencoded", "host": "www.myproject.com"}
            payload = ("grant_type=authorization_code&code={code}&client_id={client_id}&"
                        "client_secret={client_secret}&redirect_uri={redirect_uri}").format(**locals())

            response = requests.post(token_url, data=payload, headers=headers)

            if response.status_code != 200:
                return HttpResponseBadRequest(_("Bad Request"))

            authorization_info = response.json()

            access_token = authorization_info["access_token"]
            refresh_token = authorization_info["refresh_token"]
            authenticate(access_token=access_token, refresh_token=refresh_token)

            return HttpResponseRedirect(next_page)

        return None

这是我在settings.py中的内容:

MIDDLEWARE_CLASSES = (
    'django.middleware.common.CommonMiddleware',
    'django.contrib.sessions.middleware.SessionMiddleware',
    'django.contrib.auth.middleware.AuthenticationMiddleware',
    'myproject.sso.middleware.SSOMiddleware',
    'django.middleware.csrf.CsrfViewMiddleware',
    'django.contrib.messages.middleware.MessageMiddleware',
    'django.middleware.locale.LocaleMiddleware',
)

AUTHENTICATION_BACKENDS = (
    'myproject.sso.backends.SSOBackend',
    'django.contrib.auth.backends.ModelBackend',
)

===================

UPDATE:

哦......我想出来了 . 在验证用户后我遗漏了这些行:

from django.contrib.auth import authenticate, login

....

user = authenticate(access_token=access_token, refresh_token=refresh_token)
if user is not None:
    login(request, user)