일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | 6 | 7 |
8 | 9 | 10 | 11 | 12 | 13 | 14 |
15 | 16 | 17 | 18 | 19 | 20 | 21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 |
29 | 30 |
- 오블완
- 파이썬 경로 수정
- vscode무한로딩
- rds utf8mb4 변경
- rds character_set 변경
- vscode소스제어 무한로딩
- ncp api 응답오류
- command did not exit successfully docker-compose -f docker-compose.yml build exit status 1
- 파이썬버전변경
- ncp 401 authentication failed
- codebuild cliend_error
- vscode시계아이콘
- fcm 멀티푸시
- 파이썬버전여러개
- 'message': 'authentication failed'
- route53 서브도메인
- fcm multicast
- codebuild no matching artifact paths found
- ncp authentication failed
- 파이썬 설치경로 변경
- 파이썬여러버전변경
- {'error': {'errorcode': '200'
- vscode 소스제어
- 맥북파이썬여러버전
- rds 파라미터그룹
- 네이버클라우드 authentication failed
- fcm push
- codepipeline 오류
- 'details': 'invalid authentication information.'}}
- 티스토리챌린지
- Today
- Total
All that I've dreamed of
Django React 백엔드 - 클라이언트 쿠키공유 (서브도메인, Cors헤더, csrf설정) 본문
* 여기저기 알아보고 이것저것 시도해보고 정리한 내용이니 정답이 아님을 주의~!
사전 세팅
📌 백엔드: Django -> EC2 + Nginx + gunicorn 배포완료 + 도메인 설정 (예시) https://내프로젝트.com
📌 프론트엔드: React -> S3정적웹호스팅 + Cloudfront 배포완료 + 서브도메인 설정 (예시) https://www.내프로젝트.com
SOP 와 CORS 그리고 Samesite
브라우저는 SOP (동일출처정책)을 따른다.
동일 출처란 Same-Origin. 즉, 프로토콜+도메인+포트 까지 일치해야 함을 의미한다.
예) https://abcd.com:8000 서버에는 https://abcd.com:8000 의 출처만 api 요청을 허용
위 정책을 위반하게 되면 만나게 되는 에러가 CORS 에러이고
Cross-origin 교차출처의 요청을 따로 지정해서 허용해 주면 CORS 정책에 위반되지 않게 된다.
Cross-origin로 부터의 리소스를 허용
클라이언트의 요청헤더에 Origin을 명시해 주고, 서버의 응답헤더의 Access-control-allow-origin 을 설정한다.
브라우저는 자신이 보낸 origin와 응답받은 origin을 비교해서 이 둘이 일치하게 되면
동일 출처가 아닌데도 서버에서 허용했으니 리소스를 받아도 되겠구나라고 판단하게 된다.
cors 정책을 지키기 위해서는 서버에서 api 요청을 보내오는 곳의 접근을 허용한다고 설정해 주고 클라이언트에 응답해 주어야한다.
클라이언트 / 백엔드 서버에서의 설정
🙋♀️ 클라이언트 (React)
* axios를 사용하는 경우
const instance = axios.create({
URL: "https://project.com/api/v1/",
withCredentials: true,
})
🙋♀️ 백엔드 (Django )
👉 django-cors-headers 가 이미 설치/설정 되어있다는 가정 하에...
✔️참조 django-cors-headers 설치 및 세팅
https://pypi.org/project/django-cors-headers/
# settings.py
CORS_ALLOWED_ORIGINS = ["https://www.내프로젝트.com"]
CORS_ALLOW_CREDENTIALS = True
CSRF_TRUSTED_ORIGINS = ["https://www.내프로젝트.com"]
CORS_ALLOWED_ORIGINS = ["https://www.project.com"]
=> 응답헤더에 Access-Control-Allow-Origin: https://www.내프로젝트.com로 표시된다
CORS_ALLOW_CREDENTIALS = True
=> 응답헤더에 Access-Control-Allow-Credentials: true 로 표시된다
CSRF_TRUSTED_ORIGINS = ["https://www.내프로젝트.com"]
=> 이곳에 명시된 곳으로 부터의 post 요청등을 허용한다, 이 설정을 하지 않으면 csrf failed 오류가 발생
✔️ 참고
CORS_ORIGIN_WHITELIST = [] 는 CORS_ALLOWED_ORIGINS의 예전 버전(?) 이라고 한다.
물론 지금도 사용해도 되지만 두 개를 같이 쓸 경우 CORS_ALLOWED_ORIGINS이 우선한다고 한다.
https://pypi.org/project/django-cors-headers/
서브도메인 간 쿠키 공유
위의 설정들을 마쳐도 클라이언트 애플리케이션에 공유되는 쿠키가 없다면 다음 설정을 해보자..
# settings.py
SESSION_COOKIE_DOMAIN = "내프로젝트.com"
CSRF_COOKIE_DOMAIN = "내프로젝트.com"
위의 설정은 서브 크로스 도메인 간 요청을 허락해 준다
✔️ 참고: SESSION_COOKIE_DOMAIN, CSRF_COOKIE_DOMAIN
https://docs.djangoproject.com/en/4.1/ref/settings/#std-setting-SESSION_COOKIE_DOMAIN
https://docs.djangoproject.com/en/4.1/ref/settings/#std-setting-CSRF_COOKIE_DOMAIN
SESSION_COOKIE_DOMAIN
Default: None
The domain to use for session cookies. Set this to a string such as "example.com" for cross-domain cookies, or use None for a standard domain cookie.
To use cross-domain cookies with CSRF_USE_SESSIONS, you must include a leading dot (e.g. ".example.com") to accommodate the CSRF middleware’s referer checking.
(아래 번역은 내가 한거라 틀릴 수도 있음...주의)
세션 쿠키를 사용하려는 도메인
크로스 도메인간에 쿠키를 사용하고 싶으면 "example.com" 과 같이 문자열로 지정해주면 된다.
None (디폴트값)으로 하게 되면 기존 도메인(서버측 말하는 건가..?)에서만 사용할 수 있다.
CSRF_USE_SESSIONS로 크로스 도메인 쿠기를 사용하려면,
".example.com"과 같이 도메인 앞에 도트를 넣어야 한다.
궁금하니까 찾아봅시다
CSRF_USE_SESSIONS
Default: False
Whether to store the CSRF token in the user’s session instead of in a cookie. It requires the use of django.contrib.sessions.
Storing the CSRF token in a cookie (Django’s default) is safe, but storing it in the session is common practice in other web frameworks and therefore sometimes demanded by security auditors.
Since the default error views require the CSRF token, SessionMiddleware must appear in MIDDLEWARE before any middleware that may raise an exception to trigger an error view (such as PermissionDenied) if you’re using CSRF_USE_SESSIONS. See Middleware ordering.
=> 대강 요약하자면 이 설정을 사용하면 쿠키 안에 csrf token이 있더라도 django session 을 사용하게 된다
=> 이 설정을 사용하면 csrftoken의 이름이 sessionid 로 바뀌게 된다
=> 프론트엔드가 쿠키에서 csrftoken 값을 찾아서 백엔드로 보내줘야 하는데 이름을 바꾸자면 안되니까 이 설정은 사용x
CSRF_COOKIE_DOMAIN
Default: None
The domain to be used when setting the CSRF cookie. This can be useful for easily allowing cross-subdomain requests to be excluded from the normal cross site request forgery protection. It should be set to a string such as ".example.com" to allow a POST request from a form on one subdomain to be accepted by a view served from another subdomain.
Please note that the presence of this setting does not imply that Django’s CSRF protection is safe from cross-subdomain attacks by default - please see the CSRF limitations section.
csrf 쿠키를 세팅할 사용되는 도메인. 서브 크로스 도메인간 요청이 크로스 사이트의 위조방지로부터 제외되도록 해준다. 문자열로 세팅되어야 하고 서브도메인의 POST 요청을 허용해준다.
📌 최종 settings.py 설정
# settings.py
...
CORS_ALLOWED_ORIGINS = ["https://www.내프로젝트.com"]
CSRF_TRUSTED_ORIGINS = ["https://www.내프로젝트.com"]
CORS_ALLOW_CREDENTIALS = True
SESSION_COOKIE_DOMAIN = "내프로젝트.com"
CSRF_COOKIE_DOMAIN = "내프로젝트.com"
🍪서버측 쿠키
백엔드가 실행되고 있는 브라우저에서 애플리케이션에 sessionid 와 csrftoken 이 잘 들어와 있다.
이전과 다른 것이 Domain 이 그냥 내프로젝트.com 이 아닌 .내프로젝트.com 으로 되어있다는 것.
도메인 앞에 . (도트)가 붙으면 해당 루트도메인의 모든 서브도메인을 포함한다는 것 같다.
그럼 프론트엔드 브라우저에도 쿠키가 제대로 들어와 있는지 확인해 보자... 두근두근
🍪클라이언트측 쿠키
www.내프로젝트.com 프론트엔드 브라우저에도 쿠키가 잘 들어와있다...!!
로그아웃, 글 작성, 삭제 등 post 요청을 해보면 잘 된다!
'Django' 카테고리의 다른 글
[Django] 이메일 보내기 Gmail 패스워드 설정 (1) | 2023.03.29 |
---|---|
[Django] VSCode Debug 디버깅 사용하기 (0) | 2023.02.20 |
[Django] Q객체로 filter() 사용하기 (0) | 2022.12.21 |
[Django] MySQL 연동 (Docker 컨테이너) (0) | 2022.11.16 |
[Django] filter() 함수 AND / OR (0) | 2022.11.08 |