2015-11-20 2 views
0

Так что я использую 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 браузера в тот момент, когда я перехожу от этого экрана.

ответ

2

Это может быть самая тупая ошибка. Оказывается, если вы создаете пользователя без пароля, вам не нужно звонить user.set_unusable_password(). И если вы вызываете user.set_unusable_password(), это как-то испортится с любым вашим аутом (даже ПОСЛЕ того, как вы это называете).

Итак, чтобы исправить это, я просто избавился от звонка до user.set_unusable_password() в своем собственном бэкэнде django auth.

Смежные вопросы