我按照 django doc 的建议实现了一个自定义身份验证后端,我有两种方法 - 身份验证和 get_user。
我确认调用了我的自定义“身份验证”方法并返回了正确的用户,但在 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',
)