Почему моя сессия Django работает, когда я использую Postman, но не работает, когда я использую ее через React Frontend?
В настоящее время я работаю над компонентом регистрации для приложения, построенного с использованием React с TypeScript и Tailwind CSS, Django и MongoDB.
В моем Django backend у меня есть приложение под названием login_register_app
, которое используется для функциональности регистрации. Я хочу создать сессию, которая хранит id документа при его создании, чтобы, когда пользователя попросят добавить дополнительные детали на следующей странице, можно было обновить нужный документ. На данный момент у меня есть следующая функция для регистрации:
@api_view(['POST'])
def create_login(request):
# parse json
body = json.loads(request.body)
# get email and password and confirm password
email = body.get('email')
password = body.get('password')
confirm_password = body.get('confirm_password')
email_is_valid = False
password_is_valid = False
error = ''
# password must be at least 8 characters and contain digit 0 - 9, Uppercase, Lowercase and Special
# character from list (#?!@$%^&*-)
password_validation_pattern = re.compile('^(?=.*?[A-Z])(?=.*?[a-z])(?=.*?[0-9])(?=.*?[#?!@$%^&*-]).{8,}$')
# compare password to confirm password and regex pattern
if password == confirm_password and re.match(password_validation_pattern, password):
password_is_valid = True
elif password == confirm_password:
error = 'password is not valid. Requires at least one uppercase, lowercase, digit and special character [#?!@$%^&*-]'
else:
error = 'passwords do not match'
# verify email does not already exist in the database
if not users_collection.find_one({'email': email}):
email_is_valid = True
else:
error = 'email already exists'
# hash password before storing in database
hashed_password = make_password(password)
# save to database
if email_is_valid and password_is_valid:
document = users_collection.insert_one({
'email': email,
'password': hashed_password,
})
# create session to track the user id
user_id = document.inserted_id
request.session['user_id'] = str(user_id)
print(request.session.items())
return JsonResponse(
{
'emailIsValid': email_is_valid,
'passwordIsValid': password_is_valid,
'errorMessage': error
}
)
Как вы видите, после успешного создания нового документа в базе данных MongoDB создается сессия для хранения сессии под названием user_id
.
В том же файле views.py
у меня есть вторая функция, отвечающая за работу с дополнительной информацией, вводимой пользователем, такой как имя, дата рождения и т.д. Чтобы правильно обновить соответствующий документ, я пытаюсь получить доступ к сессии, которую я ранее создал, используя document = users_collection.find_one({"_id": bson.ObjectId(request.session['user_id'])})
, как показано в коде ниже:
Однако, когда я делаю это, я получаю KeyError, предполагающий, что ключ user_id
не существует в словаре сессии, но когда я проверяю словарь сессии после первоначального создания сессии, я вижу, что он там есть, как показано в стек-трассе ниже, где словарь сессии для первого вызова API (login-register/create-login/
) находится в строке 1 стек-трассы, а словарь сессии для второго вызова API (login-register/core-details/
) можно увидеть в строке 3 стек-трассы:
dict_items([('user_id', '63e0f975611b8440139c674c')])
[06/Feb/2023 12:58:29] "POST /login-register/create-login/ HTTP/1.1" 200 67
dict_items([])
Internal Server Error: /login-register/core-details/
Traceback (most recent call last):
File "C:\Users\bench\Documents\GitHub\z12-performance-webapp\server\.venv\Lib\site-packages\django\core\handlers\exception.py", line 55, in inner
response = get_response(request)
^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\bench\Documents\GitHub\z12-performance-webapp\server\.venv\Lib\site-packages\django\core\handlers\base.py", line 197, in _get_response
response = wrapped_callback(request, *callback_args, **callback_kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\bench\Documents\GitHub\z12-performance-webapp\server\.venv\Lib\site-packages\django\views\decorators\csrf.py", line 54, in wrapped_view
return view_func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\bench\Documents\GitHub\z12-performance-webapp\server\.venv\Lib\site-packages\django\views\generic\base.py", line 103, in view
return self.dispatch(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\bench\Documents\GitHub\z12-performance-webapp\server\.venv\Lib\site-packages\rest_framework\views.py", line 509, in dispatch
response = self.handle_exception(exc)
^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\bench\Documents\GitHub\z12-performance-webapp\server\.venv\Lib\site-packages\rest_framework\views.py", line 469, in handle_exception
self.raise_uncaught_exception(exc)
File "C:\Users\bench\Documents\GitHub\z12-performance-webapp\server\.venv\Lib\site-packages\rest_framework\views.py", line 480, in raise_uncaught_exception
raise exc
File "C:\Users\bench\Documents\GitHub\z12-performance-webapp\server\.venv\Lib\site-packages\rest_framework\views.py", line 506, in dispatch
response = handler(request, *args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\bench\Documents\GitHub\z12-performance-webapp\server\.venv\Lib\site-packages\rest_framework\decorators.py", line 50, in handler return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\bench\Documents\GitHub\z12-performance-webapp\server\login_register_app\views.py", line 175, in add_core_user_details
document = users_collection.find_one({"_id": bson.ObjectId(request.session['user_id'])})
~~~~~~~~~~~~~~~^^^^^^^^^^^
File "C:\Users\bench\Documents\GitHub\z12-performance-webapp\server\.venv\Lib\site-packages\django\contrib\sessions\backends\base.py", line 53, in __getitem__
return self._session[key]
~~~~~~~~~~~~~^^^^^
KeyError: 'user_id'
Больше всего меня смущает то, что когда я тестирую эту функциональность с помощью Postman, она работает как задумано, т.е. сессия сохраняется при первом вызове API и доступна для второго вызова API, позволяя документу правильно обновляться в базе данных MongoDB. Но когда я использую свой фронтенд React, это не работает так же, как показано в приведенной выше трассировке стека. Это привело меня к первоначальному мнению, что это проблема фронтенда, однако после тестирования я убедился, что данные правильно передаются от фронтенда к бэкенду.
Любая помощь будет очень признательна!