Как получить информацию о пользователе из базы данных, когда единственным в клиентском браузере является authToken?

#reactjs #django #cookies #django-rest-framework

#reactjs #django #файлы cookie #django-rest-framework

Вопрос:

Создаю свое первое приложение с реальным бэкэндом.

В моем приложении, когда пользователь регистрируется или входит в систему (с именем пользователя и паролем), токен сохраняется в файлах cookie их браузера. После регистрации (или при входе в систему) я могу легко вернуть информацию, относящуюся к этому конкретному пользователю (имя, идентификатор и т. Д.).

 # Django REST backend for loggin in and getting user token
class CustomAuthToken(ObtainAuthToken):

    def post(self, request, *args, **kwargs):
        serializer = self.serializer_class(
            data=request.data, context={'request': request})
        serializer.is_valid(raise_exception=True)
        user = serializer.validated_data['user']
        token, created = Token.objects.get_or_create(user=user)

        return Response({
            'token': token.key,
            'user_id': user.pk,
            'email': user.email,
            'user_type': user.user_type,
        })
  

В следующий раз, когда пользователь получит доступ к приложению на том же устройстве, токен будет там, и я смогу отправлять http-запросы, для которых необходим токен. Однако, поскольку я не буду снова регистрировать пользователя (не запрашивая имя пользователя и пароль каждый сеанс), я не получу дополнительную информацию этого пользователя.

В моем приложении React я хотел бы, чтобы пользователь всегда находился в состоянии, например user = {first_name: 'john', user_type: 'p'} , но я не знаю, как получить информацию о пользователе, когда единственное, что у меня есть, это их токен.

Я более чем приветствую критику этого подхода и изучение наилучшего способа сделать это. Я даже не знаю, правильно ли поддерживать пользователя в состоянии…

Я попробовал это:

 
class UserAPI(generics.RetrieveUpdateAPIView):
    serializer_class = UserSerializer

    def get_object(self):
        print(self.request.user)
        return self.request.user


curl -H "Authorization: Token b2e33463esdf8as7d9f8j34lf98sd8a" http://localhost:8000/current-user/
  

но возвращаемое значение из self.request.user является AnonymousUser

Ответ №1:

Если это не конфиденциальная информация, такая как имя пользователя, идентификатор, тип пользователя, имя и т. Д. вы можете сохранить это в localStorage.

Комментарии:

1. мы переходим к SO! это не сработает для моего варианта использования. Представьте, что мне нужно получить данные из других конечных точек и указать идентификатор пользователя в этих запросах. просто изменив user_id в localStorage, можно получить доступ к данным, относящимся к другим пользователям.

Ответ №2:

проблема была в моем settings.py файл:

   'DEFAULT_AUTHENTICATION_CLASSES': (
      'rest_framework.authentication.TokenAuthentication',
)
  

Ответ №3:

На этот вопрос есть две части ответа. первая часть — это критика вашего подхода и небольшое руководство по улучшению подхода, вторая часть ответа касается вашего фактического вопроса.

Давайте сначала начнем со второй части. Судя по вашему коду, вы уже сохраняете таблицу key in Token вместе с. User Вы можете легко получить пользователя, сначала выполнив этот запрос token = Token.objects.get(key=key).select_related('user') , а затем simple user = token.user предоставит вам токен.

Теперь перейдем к первой части. Поскольку вы используете DRF, вам не нужно переопределять класс, если это не является крайне необходимым. Если вы хотите, чтобы пользователь отвечал за каждый одобренный запрос, вы можете просто добавить свой класс проверки токена в настройки DRF

Ответ №4:

У меня была такая же проблема, но я нашел, как это сделать, этот код поможет вам

         if request.user.is_authenticated:
        user = Account.objects.filter(username=request.user)
        serializer = UserSerializer(user, many=True)
        return Response(serializer.data)
    else:
        return Response('You have to login first')