我按照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)