diff --git a/README.md b/README.md
index 8fb1b86..5dc1ef2 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,54 @@
# oz_03_collabo-002-BE
합동 프로젝트 2팀 리포지토리입니다.
+
+www.malazoo.kr
+
+https://api.malazoo.kr/v1/schema/redoc
+
+## ⚙️ 사용 기술
+
+### BackEnd
+
+![python](https://img.shields.io/badge/Python-3776AB?style=for-the-badge&logo=python&logoColor=white)
+![django](https://img.shields.io/badge/Django-092E20?style=for-the-badge&logo=django&logoColor=white)
+![postgres](https://img.shields.io/badge/PostgreSQL-316192?style=for-the-badge&logo=postgresql&logoColor=white)
+![Poetry](https://img.shields.io/badge/Poetry-%233B82F6.svg?style=for-the-badge&logo=poetry&logoColor=0B3D8D)
+![DjangoREST](https://img.shields.io/badge/DJANGO-REST-ff1709?style=for-the-badge&logo=django&logoColor=white&color=ff1709&labelColor=gray)
+![JWT](https://img.shields.io/badge/JWT-black?style=for-the-badge&logo=JSON%20web%20tokens)
+![Docker](https://img.shields.io/badge/docker-%230db7ed.svg?style=for-the-badge&logo=docker&logoColor=white)
+![GitHub Actions](https://img.shields.io/badge/github%20actions-%232671E5.svg?style=for-the-badge&logo=githubactions&logoColor=white)
+
+
+![PayPal](https://img.shields.io/badge/PayPal-00457C?style=for-the-badge&logo=paypal&logoColor=white)
+
+
+## 🗓프로젝트 기간
+- **기본요구사항 : 24.08.06 ~ 24.09.09**
+
+## 👤멤버 구성
+
+### Team
+|
|
|
+|:-:|:-:|
+|[@im-niber](https://github.com/im-niber)|[@Gomnonix](https://github.com/Gomnonix)|
+
+
+## 구현 기능
+- 일일 클래스 정보 구현
+- 클래스 예약 기능 구현
+- 프로필 사진 변경, 닉네임 변경 및 소셜로그인 구현
+- 포토리뷰, 리뷰 좋아요, 즐겨찾기 클래스 기능 구현
+- django admin 커스텀 기능 추가(최근 수정 내역 알림기능)
+- 무중단 배포 및 CI 구현
+
+## ERD
+
+![erd.png](images/erd.png)
+
+## Architecture
+
+![architecture.png](images/architecture.png)
+
+
+
diff --git a/customk/users/services/token_service.py b/customk/users/services/token_service.py
index b5d960f..dbd8301 100644
--- a/customk/users/services/token_service.py
+++ b/customk/users/services/token_service.py
@@ -22,8 +22,36 @@ def generate_tokens(user: User) -> Token:
return Token(str(refresh), str(refresh.access_token)) # type: ignore
+def get_cookie_domain(env: str) -> str | None:
+ if env == "production":
+ return os.environ.get("DOMAIN_NAME")
+ return None
+
+
+def set_token_cookie(
+ response: Response, name: str, token: str, max_age: int, front_env: str
+) -> None:
+ domain = get_cookie_domain(front_env)
+
+ response.set_cookie(
+ key=name,
+ value=token,
+ max_age=max_age,
+ httponly=True,
+ secure=(front_env != "development"),
+ samesite="Lax" if front_env == "development" else "None",
+ domain=domain if domain else None,
+ )
+
+
def set_cookies(request: Request, response: Response, token: Token) -> Response:
- logger.info("Set cookie")
+ host = request.get_host()
+ logger.info(f"Setting cookies domain: {host}")
+
+ if host and str(os.getenv("DOMAIN_NAME")) in host:
+ front_env = "production"
+ else:
+ front_env = "development"
access_max_age = int(
cast(timedelta, settings.SIMPLE_JWT["ACCESS_TOKEN_LIFETIME"]).total_seconds()
@@ -32,31 +60,11 @@ def set_cookies(request: Request, response: Response, token: Token) -> Response:
cast(timedelta, settings.SIMPLE_JWT["REFRESH_TOKEN_LIFETIME"]).total_seconds()
)
- response.set_cookie(
- "access_token",
- token.access_token,
- max_age=access_max_age,
- secure=True,
- httponly=True,
- domain=os.environ.get("DOMAIN_NAME"),
+ set_token_cookie(
+ response, "access_token", token.access_token, access_max_age, front_env
)
-
- response.set_cookie(
- "refresh_token",
- token.refresh_token,
- max_age=refresh_max_age,
- secure=True,
- httponly=True,
- domain=os.environ.get("DOMAIN_NAME"),
+ set_token_cookie(
+ response, "refresh_token", token.refresh_token, refresh_max_age, front_env
)
- if hasattr(response, "data"):
- response.data["access_token"] = token.access_token
- response.data["refresh_token"] = token.refresh_token
- else:
- response.data = {
- "access_token": token.access_token,
- "refresh_token": token.refresh_token,
- }
-
return response
diff --git a/customk/users/views/token.py b/customk/users/views/token.py
index e2b5d7e..bb2617f 100644
--- a/customk/users/views/token.py
+++ b/customk/users/views/token.py
@@ -1,6 +1,4 @@
-import os
-from datetime import timedelta
-from typing import Any, cast
+from typing import Any
from drf_spectacular.utils import (
OpenApiExample,
@@ -14,8 +12,8 @@
from rest_framework_simplejwt.exceptions import InvalidToken
from rest_framework_simplejwt.views import TokenRefreshView, TokenVerifyView
-from config import settings
from config.logger import logger
+from users.services.token_service import Token, set_cookies
class CustomTokenRefreshView(TokenRefreshView):
@@ -70,22 +68,12 @@ def post(self, request: Request, *args: Any, **kwargs: Any) -> Response:
response = super().post(request)
if response.status_code == 200:
- access_token = response.data.get("access")
-
- domain = os.environ.get("DOMAIN_NAME")
- access_max_age = int(
- cast(
- timedelta, settings.SIMPLE_JWT["ACCESS_TOKEN_LIFETIME"]
- ).total_seconds()
- )
- response.set_cookie(
- key="access_token",
- value=access_token,
- max_age=access_max_age,
- domain=domain,
- httponly=True,
- secure=True,
- )
+ new_refresh_token = response.data.get("refresh")
+ new_access_token = response.data.get("access")
+ tokens = Token(new_refresh_token, new_access_token)
+
+ response = set_cookies(request, response, tokens)
+
del response.data["access"]
del response.data["refresh"]
diff --git a/images/architecture.png b/images/architecture.png
new file mode 100644
index 0000000..1a13336
Binary files /dev/null and b/images/architecture.png differ
diff --git a/images/erd.png b/images/erd.png
new file mode 100644
index 0000000..382463c
Binary files /dev/null and b/images/erd.png differ