Как устранить ошибку "HTTP-заголовок токена X-Csrf имеет неверную длину" в React Native с помощью Django API?
Программа должна выполнить POST-запрос для выхода из клиента React Native (Android с Expo Go), завершив его сеанс. Программа сохраняет идентификатор сеанса пользователя и токен CSRF из ответа Django после входа в систему с помощью React Native AsyncStorage. И при попытке выполнить запрос на выход из системы, отправив идентификатор сеанса и токен CSRF в качестве заголовков, программа выдает ошибку заголовка.
Запрос на выход из системы
const postRequestLogout = async () => {
try {
//getting both sessionid and csrftoken from asycStorage
const sessionid_value = await AsyncStorage.getItem('sessionid')
const csrftoken_value = await AsyncStorage.getItem('csrftoken')
console.log("Session: ",sessionid_value)
console.log("Csrf: ",csrftoken_value)
//Here these values are passed to headers
const requestOptions = {method:'POST',headers: {'Content-Type': 'application/json','Authorization':sessionid_value,'X-CSRFTOKEN':csrftoken_value}}
await fetch(
'http://myIP/user_account/api_logout_user_account/', requestOptions)
.then(response => {
response.json()
.then(data => {
Alert.alert("Sucesss");
console.log(data)
});
})
} catch(e) {
console.log(e)
}
}
Запрос на вход в систему
const PostRequestLogin = () => {
const email = "myemail"
const password = "mypass"
setSessionId = async (value) => {
try {
await AsyncStorage.setItem('sessionid', JSON.stringify(value))
} catch(e) {
console.log(e)
}
}
setCsrfToken = async (value) => {
try {
await AsyncStorage.setItem('csrftoken', JSON.stringify(value))
} catch(e) {
console.log(e)
}
}
const requestOptions = {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email:email,password:password})
};
const postRequestLogin = async () => {
try {
await fetch(
'http://myIP/user_account/api_login_user_account/', requestOptions)
.then(response => {
response.json()
.then(data => {
if(data.sessionid && data.csrftoken){
Alert.alert("Sucesss");
console.log(data);
setSessionId(data.sessionid)
setCsrfToken(data.csrftoken)
}
else{
Alert.alert("No SessionId or CSRF TOKEN Received!");
console.log("No SessionId or CSRF TOKEN Received!");
}
});
})
}
catch (error) {
console.error(error);
}
}
Пример того, как значение пары токенов CSRF выглядит в консоли:
" csrftoken": "IRFxHgM5LYbhPYNXWHqghBK7IETPnxDEx0TYp4loWKpxcj3DStLTLIhBmAl58ВОу"
А это часть кода того, как Django API отправляет информацию клиенту (после входа в систему):
request.session.save()
serializer_response = LoginUserAccountSerializer(data={'email': email,'password':password,'sessionid':request.session.session_key,'csrftoken':get_token(request)})
if serializer_response.is_valid():
login(request, user)
return Response(serializer_response.data,status=status.HTTP_202_ACCEPTED)
Для тех, кто заинтересован, я решил отключить защиту Django от CSRF, и теперь мобильный клиент (в частности, Android) может запросить выход из системы, отправив только идентификатор сеанса в качестве заголовка.
Проверить, как это отключить , можно здесь, предоставлено пользователем Saeed