I am developing a webApp. My backend is on xxx.xxx.xxx.xxx:8000 and my frontend is on xxx.xxx.xxx.xxx:3000. I am using Django and ReactJS. I have configured my CORS policies on the backend to allow only my fronted to make requests.
So. Whenever I have to get CSRF cookies from my backend they come in a response under Set-Cookie
with HttpOnly
flag.
My question is if we are not supposed to extract HttpOnly cookies with the JS how come I still can do that with my ReactJS app. However, whenever I remove that flag I cannot set or retrieve those cookies from the header anymore. Whta is wrong? Or what is right?
Help me to understand that please.
my django CORS setup:
# CSRF Cookie Settings
CSRF_COOKIE_AGE: Optional[int] = None
CSRF_TRUSTED_ORIGINS = [
'http://localhost:3000',
'http://xxxx.xxxx.xxxx.xxxx:3000'
]
CSRF_COOKIE_HTTPONLY = True
# CORS(cross origin resource sharing) settings
CORS_ORIGIN_ALLOW_ALL = False
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOWED_ORIGINS = [
'http://localhost:3000',
'http://xxxx.xxxx.xxxx.xxxx:3000',
]
CORS_ALLOW_METHODS = [
'DELETE',
'GET',
'PATCH',
'POST',
'PUT',
]
my reactjs request:
fetch("http://xxxx.xxxx.xxxx.xxxx:8000/get_csrf",{
method: 'GET',
mode: 'cors',
credentials:'same-origin',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
}
})
.then(response => {
console.log(...response.headers)
response.json()
})
.then(
(result) => {
console.log(this.getCookie('csrftoken'))
},
(error) => {
}
)
CodePudding user response:
TL;DR
You cannot.
More details
My backend is on xxxx.xxxx.xxxx.xxxx:8000 and my frontend is on xxxx.xxxx.xxxx.xxxx:3000.
Note that your request is cross-origin.
Be aware that the Fetch Standard (the de facto CORS specification) categorises Set-Cookie
as a forbidden response-header name. Therefore, regardless of the server's CORS configuration, browsers do not allow a client to read such headers from the response to a cross-origin request.
The MDN Web Docs about the Set-Cookie
response header, which may be a nonauthoritative source of truth but is easier to read than the Fetch Standard, contains this clarifying warning:
Browsers block frontend JavaScript code from accessing the
Set-Cookie
header, as required by the Fetch spec, which definesSet-Cookie
as a forbidden response-header name that must be filtered out from any response exposed to frontend code.
CodePudding user response:
So I have gathered a bit more information and have found out how to set it up correctly.
- Yes, we cannot access
HttpOnly
cookies. - Need to have
credentials:'include'
in the fetch JS request. - Need to have
mode: 'cors'
in the fetch JS request. - In Django
settings.py
:
CORS_ORIGIN_ALLOW_ALL = False
CORS_ALLOW_CREDENTIALS = True
CORS_ALLOWED_ORIGINS = [
'http://localhost:3000',
'http://xxx.xxx.xxx.xxx:3000',
]
CORS_ALLOW_METHODS = [
'DELETE',
'GET',
'PATCH',
'POST',
'PUT',
]
CORS_EXPOSE_HEADERS = [
'Date'
]