Первый вызов django rest api возвращает request.user как AnonymousUser, но последующие вызовы возвращают правильного пользователя
Прямо сейчас у меня есть представление api, которое требует знать, какой пользователь в настоящее время вошел в систему. Когда я пытаюсь вызвать его с зарегистрированным пользователем, однако, он возвращает анонимного пользователя. Странно то, что если я вызываю api представление снова, оно возвращает правильного пользователя. Я использую django rest framework и JSON Web Tokens с помощью simplejwt. Сейчас вызов в ReactJS выглядит следующим образом:
const fetchAuthorData = () => {
axiosInstance.get('authors/')
.then((res) => {
setAuthor(res.data)
}).catch((err) => {
fetchAuthorData()
})
fetchAuthorThreads()
fetchAuthorArticles()
}
Однако я знаю, что рекурсивное обращение к этому снова и снова очень опасно, потому что даже если я перенаправляю, если пользователь действительно не вошел в систему до этого рекурсивного вызова api, если каким-то образом это не удастся, мой сервер будет перегружен вызовами api. Кто-нибудь знает, как я могу сделать так, чтобы мой api действительно правильно определял при первом вызове, вошел ли пользователь в систему?
Вот ошибочное мнение:
@api_view(['GET'])
def author(request):
print(request.user)
if request.user.is_authenticated:
author = request.user
serializer = AuthorAccessSerializer(author, many=False)
return Response(serializer.data)
else:
return HttpResponse(status=400)
В этом случае request.user является анонимным пользователем, хотя я вошел в систему
Вот аналогичная часть другого представления, которая работает странно
@api_view(['GET', 'POST'])
def articles(request):
if request.method == 'GET':
category_name = request.query_params['category']
dash = request.query_params['dash']
#this part is very similiar and works for some reason
if dash == "True":
if request.user.is_authenticated:
articles = Article.objects.filter(author=request.user)
else:
return HttpResponse(status=401)
# *end part*
elif category_name:
try:
category = Category.objects.get(name__icontains=category_name)
except:
return HttpResponse(status=400, content="Category not found")
articles = Article.objects.filter(category=category)
else:
articles = Article.objects.all()
serializer = ArticleSerializer(articles, many=True)
return Response(serializer.data)
Вот мои настройки axios:
export const axiosInstance = axios.create({
baseURL: baseURL,
timeout: 5000,
headers : {
Authorization: localStorage.getItem('access_token')
? 'JWT' + localStorage.getItem('access_token')
: null,
'Content-Type' : 'application/json',
accept : 'application/json'
}
})
А вот мои настройки rest framework и JWT auth:
REST_FRAMEWORK = {
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.AllowAny'
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework_simplejwt.authentication.JWTAuthentication',
),
}
SIMPLE_JWT = {
'ACCESS_TOKEN_LIFETIME': timedelta(hours=5),
'REFRESH_TOKEN_LIFETIME': timedelta(days=1),
'ROTATE_REFRESH_TOKENS': False,
'BLACKLIST_AFTER_ROTATION': True,
'UPDATE_LAST_LOGIN': False,
'ALGORITHM': 'HS256',
'SIGNING_KEY': SECRET_KEY,
'VERIFYING_KEY': None,
'AUDIENCE': None,
'ISSUER': None,
'JWK_URL': None,
'LEEWAY': 0,
'AUTH_HEADER_TYPES': ('Bearer', 'JWT'),
'AUTH_HEADER_NAME': 'HTTP_AUTHORIZATION',
'USER_ID_FIELD': 'id',
'USER_ID_CLAIM': 'user_id',
'USER_AUTHENTICATION_RULE': 'rest_framework_simplejwt.authentication.default_user_authentication_rule',
'AUTH_TOKEN_CLASSES': ('rest_framework_simplejwt.tokens.AccessToken',),
'TOKEN_TYPE_CLAIM': 'token_type',
'JTI_CLAIM': 'jti',
'SLIDING_TOKEN_REFRESH_EXP_CLAIM': 'refresh_exp',
'SLIDING_TOKEN_LIFETIME': timedelta(minutes=5),
'SLIDING_TOKEN_REFRESH_LIFETIME': timedelta(days=1),
}
ALLOWED_HOSTS=['127.0.0.1', 'http://localhost:5000']
CORS_ORIGIN_ALLOW_ALL = False
CORS_ORIGIN_WHITELIST = (
'http://localhost:3000',
)
Опять же, если я продолжаю вызывать тот же api вызов, он почему-то работает, не изменяя никаких заголовков авторизации, токенов или чего-либо еще, и request.user работает нормально со вторым представлением, которое у меня есть выше. Может ли кто-нибудь сказать мне, почему это происходит?
Я думаю,
1. localStorage.setItem('access_token', response.data.access)
2. localStorage.setItem('refresh_token', response.data.refresh)
3. axiosInstance.defaults.headers['Authorization'] =
'JWT ' + localStorage.getItem('access_token')
history.push('/')
код входа в систему может вызвать проблему.
Этот код никогда не выполняется последовательно; каждый javascript выполняется асинхронно.
Значит, ваш axiosInstance.defaults.headers
может быть нулевым, потому что 1, 2 и 3 строки выполняются одновременно. Другими словами, axiosInstance.defaults.headers
становится нулевым (так как нет access_token на localStorage), тогда, Js устанавливает access_token из response.data.access
.
Вам лучше использовать обещание с .then()
после 1 и 2 строки,
или получить авторизацию axiosInstance при выполнении http запроса.