Так что я использую Rdio для входа и создания пользователей и написал бэкэнд для обработки его oauth. При первом попытке входа в систему с помощью Rdio он создает пользователя и подключенного пользователя Rdio, но он не создает сеанс и не возвращает cookie сеанса.Пользовательский сервер проверки подлинности django не регистрирует пользователя в первый раз, но работает второй раз
Поток похож на любой поток oauth2: вы нажимаете кнопку на моем приложении, перенаправляете w/get params в Rdio, а Rdio вызывает обратный вызов в моем приложении (вместе с кодом в параметрах GET). В этой точке зрения обратного вызова, звоню аутентификации:
class RdioCallbackView(View):
def get(self, request):
""" here, you need to create and auth a django user and create and tie the rdio user's stuff to it """
if request.user.is_authenticated() == False:
try:
rdio_code = request.GET['code']
except KeyError:
return redirect(reverse('login'))
# authenticate
user = auth.authenticate(rdio_code=rdio_code)
if user is not None and user.is_active:
auth.login(request, user)
else:
return render(request, 'home/login.html', {'rdio_url': create_rdio_auth_url(), 'message': "That code didn't seem to work"})
else:
# user exists!
user = request.user
return HttpResponseRedirect(reverse('the-next-view'))
Обычай аутентификации бэкенд выглядит следующим образом:
class RdioBackend(object):
def authenticate(self, rdio_code=None):
token_info = exchange_rdio_code(rdio_code)
try:
access_token = token_info['access_token']
refresh_token = token_info['refresh_token']
except KeyError:
return None
except TypeError:
# the code was probably already used.
return None
rdio_user_dict = get_rdio_user_for_access_token(access_token)
rdio_key = rdio_user_dict['key']
try:
rdio_user = RdioUser.objects.get(rdio_id=rdio_key)
rdio_user.access_token = access_token
rdio_user.refresh_token = refresh_token
rdio_user.save()
user = rdio_user.user
except RdioUser.DoesNotExist:
user = User.objects.create(username=rdio_key)
user.set_unusable_password()
rdio_user = RdioUser.objects.create(
rdio_id = rdio_key,
access_token = access_token,
refresh_token = token_info['refresh_token'],
user = user,
)
return user
def get_user(self, user_id):
try:
return User.objects.get(pk=user_id)
except User.DoesNotExist:
return None
И где все становится странно. Кажется, он не создает новый объект Session и определенно не возвращает cookie сеанса. Тем не менее, когда я снова возвращаюсь и снова регистрирую Rdio, он возвращает cookie сеанса, делает сеанс на сервере, а логин и auth работают отлично.
И я думаю, что мои настройки AUTHENTICATION_BACKENDS прав:
AUTHENTICATION_BACKENDS = (
'appname.backend.RdioBackend',
'django.contrib.auth.backends.ModelBackend',
)
Edit: Более возможно соответствующую информацию: Взгляды, что он перенаправляет иметь LoginRequiredMixin:
class LoginRequiredMixin(object):
@classmethod
def as_view(cls, **initkwargs):
view = super(LoginRequiredMixin, cls).as_view(**initkwargs)
return login_required(view)
И в RdioCallbackView, когда Я меняю окончательную строку с return HttpResponseRedirect(reverse('the-next-view'))
, а вместо этого просто обслуживаю шаблон напрямую с return render(request, 'path/to.html', param_dict)
, он служит файлу cookie и делает sessionid, но затем он удаляет его из БД и из e браузера в тот момент, когда я перехожу от этого экрана.