From a766ae5227408e9c1af4c6a0961f491af402dfe4 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Sat, 11 Jan 2025 15:45:34 +0900 Subject: [PATCH 1/8] =?UTF-8?q?[DOCS]=20README=20-=20Tech=20Stack=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/README.md b/README.md index 2ffd19b..84586e0 100644 --- a/README.md +++ b/README.md @@ -1 +1,25 @@ # sopt-auth-backend +> _**Updated at.** 2025/01/11 (Sat)_
+> _**Updated by.** [@yummygyudon](https://www.github.com/yummygyudon)_ + +SOPT 회원들이 SOPT makers 프로덕트를 사용하기 위한 **인증**과 **로그인/회원가입 기능**을 지원합니다. + + +## Tech Stack +- **Language** : Java 21 +- **Framework** : Spring Framework + - Spring Boot + - Spring Data JPA + - Spring Security (Starter, OAuth 2.0 Resource Server) + - Java JWT (`jjwt`) +- **Deploy** : Github Actions, AWS S3, AWS ECR, Docker +- **Test** + - JUnit5 + - Mockito + - Rest Assured + - Fixture Monkey(1.0.25) + - Archunit(1.3.0) +- **Client** : OKHttp + +
+ From b1bec62273f0dbdaad9080d7918634fe8bce1dbd Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Sat, 11 Jan 2025 15:52:43 +0900 Subject: [PATCH 2/8] =?UTF-8?q?[DOCS]=20README=20-=20Conventions=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 56 insertions(+) diff --git a/README.md b/README.md index 84586e0..d84a8ba 100644 --- a/README.md +++ b/README.md @@ -23,3 +23,59 @@ SOPT 회원들이 SOPT makers 프로덕트를 사용하기 위한 **인증**과
+ +## Conventions +**협업 프로세스**는 아래와 같습니다. +1. **github issue 생성** + - 템플릿에 맞춰 Issue 작성 + - Assignees, Label 할당 + - 단, "사소한 변경의 HOTFIX"인 경우, 구체적인 커밋 메시지 작성을 통해 전달 +2. **branch 생성** + - 형식 : `{Issue Tag}/#{Issue Number}` (ex. `feat/#1`) +3. **로컬 작업** + - **기능단위** 커밋 지향 +4. 해당 issue에 대한 작업 완료 시, `dev` 브랜치로 **해당 브랜치 Pull Request 제출** + - 템플릿에 맞춰 PR 작성 + - Assignees, Label 할당 + - `prod` 브랜치에 대한 PR의 경우, 버전 반영에 영향이 있기 때문에 반드시 적절한 Label을 할당합니다. +5. 리뷰어가 전원 Approve 때까지 리뷰를 주고받으며 기능 수정 반복 +6. 리뷰어 전원 Approve 시, merge + - `feature branch` → `dev` → `prod` + +> **프로젝스 소스코드 외** (환경변수, db 필드 및 테이블 수정, 인프라 세팅 등) 수정사항이 있을 경우,
+> 팀원에게 먼저 물어보고 진행하거나, 그러지 못하였더라면 빠르게 전달해야 합니다 (카톡, 슬랙, 디코 등) + +
+ +### 🔖 Issue / Commit Tag +| Tag | Description | +|:-------------|:-------------------------------| +| `[ADD]` | 주요 기능 관련 코드/파일 추가 | +| `[MODIFY]` | 주요 기능 관련 코드/파일 수정 | +| `[DEL]` | 주요 기능 관련 코드/파일 제거 | +| `[CHORE]` | 주요 기능 **외** 코드/파일 추가 및 수정 | +| `[FEAT]` | 기능 구현 | +| `[FIX]` | 기능 버그 및 오류 해결 | +| `[HOTFIX]` | Issue / QA 과정에서의 급한 버그 및 오류 해결 | +| `[DOCS]` | README/WIKI 등의 문서 작업 | +| `[REFACTOR]` | 기능/성능/코드 개선 작업 | + +
+ +### Branch Strategy +기본적으로 "**Git Flow**" 전략을 바탕으로 적용했습니다. +- `main`, `dev`, `feature` 브랜치 구성 +- `main` : **production**용 브랜치 + - 실서비스용 ec2(**makers.operation.prod)**로 배포되도록 파이프라인이 구축되어 있습니다 +- `dev` : **development**용 브랜치 + - 테스트용 ec2(**makers.operation)**로 배포되도록 파이프라인이 구축되어 있습니다 + - default 브랜치 입니다 +- `feature` : **Isuue** 브랜치 + - 각자 이슈에 대한 작업물 브랜치 + - 이슈에 따라 브랜치 Prefix 지정 (feat/fix/modify 등) + - 형식 = `{이슈 종류}/#{이슈번호}` + - `main` 직접적인 PR 불가능 (`dev` PR을 거쳐 merge) + +
+ + From 7e4734b24bc4c414e96a8e4257225e341b110144 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Sat, 11 Jan 2025 15:53:41 +0900 Subject: [PATCH 3/8] =?UTF-8?q?[DOCS]=20README=20-=20Author=20=EC=9E=91?= =?UTF-8?q?=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index d84a8ba..7201548 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,6 @@ SOPT 회원들이 SOPT makers 프로덕트를 사용하기 위한 **인증**과 **로그인/회원가입 기능**을 지원합니다. - ## Tech Stack - **Language** : Java 21 - **Framework** : Spring Framework @@ -23,7 +22,6 @@ SOPT 회원들이 SOPT makers 프로덕트를 사용하기 위한 **인증**과
- ## Conventions **협업 프로세스**는 아래와 같습니다. 1. **github issue 생성** @@ -78,4 +76,12 @@ SOPT 회원들이 SOPT makers 프로덕트를 사용하기 위한 **인증**과
+## Authors +- 정동규 : [@yummygyudon](https://www.github.com/yummygyudon) +- 김성은 : [@sung-silver](https://www.github.com/sung-silver) +- 강현욱 : [@hyunw9](https://www.github.com/hyunw9) + +![Alt](https://repobeats.axiom.co/api/embed/7ecaed933101e79c17cea76035d79ea7afff6565.svg "Repobeats analytics image") + +
From dd0c83627c3a765b02ede1f726b41a3fbffd7e43 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Sat, 11 Jan 2025 16:11:36 +0900 Subject: [PATCH 4/8] =?UTF-8?q?[DOCS]=20README=20-=20More=20About:Architec?= =?UTF-8?q?ture=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/README.md b/README.md index 7201548..bca284b 100644 --- a/README.md +++ b/README.md @@ -85,3 +85,30 @@ SOPT 회원들이 SOPT makers 프로덕트를 사용하기 위한 **인증**과
+## More About +### Application Architecture 🧸 +기본적으로 "**도메인 주도 개발**(DDD)"를 기조로 설계했습니다. +- 유저의 권한, 인증 기능을 다루는 프로젝트인만큼 테스트의 중요도가 높다고 판단하여 도메인에 대한 "**테스트 용이성**" 효용을 취하기 위함. +- SOPT의 경우, 6개월의 활동 주기를 가지며 각 기수마다의 유저 정책 변동성이 존재한다고 판단하여 "**유연성**" 및 "**도메인 독립성**" 효용을 취하기 위함 + +![img.png](https://miro.medium.com/v2/resize:fit:1400/format:webp/1*JOSyX8Ck85HrJ2WhU_jMcQ.png) +(이미지 출처 : https://medium.com/@hello-every-one/hexagonal-architecture-3729e9a9200b) + +
+ +### Server Architecture ☁️ +1. **Merge & Trigger** Github Actions +2. **Run Deploy Workflow** Script + - [dev script](./.github/workflows/cd-dev.yml) + - [prod script](./.github/workflows/cd-prod.yml) +3. **Copy Files from AWS S3** +4. **Build and Push Image to ECR** +5. **Send Files to EC2** by SCP +6. **Connect to EC2** by SSH +7. **Run Deploy Scripts** with receive files +8. **Deploy** application on Docker Container + + +![server_architecture_img.png](https://yummygyudon.notion.site/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F10896002-67a1-441c-9cea-b6f696faae26%2F36522594-3b8d-4995-b24e-fded2b1779e9%2Fimage.png?table=block&id=17779bee-8167-8007-92c1-c4b1fc0800cf&spaceId=10896002-67a1-441c-9cea-b6f696faae26&width=1420&userId=&cache=v2) + +
From 5c5009611a614433c8527af043a03e538fe4890c Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Sat, 11 Jan 2025 17:35:43 +0900 Subject: [PATCH 5/8] =?UTF-8?q?[DOCS]=20README=20-=20More=20About:Features?= =?UTF-8?q?&Environment=20Variables=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index bca284b..84e0b67 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ SOPT 회원들이 SOPT makers 프로덕트를 사용하기 위한 **인증**과
-### Branch Strategy +### Branch Strategy 🌵 기본적으로 "**Git Flow**" 전략을 바탕으로 적용했습니다. - `main`, `dev`, `feature` 브랜치 구성 - `main` : **production**용 브랜치 @@ -112,3 +112,23 @@ SOPT 회원들이 SOPT makers 프로덕트를 사용하기 위한 **인증**과 ![server_architecture_img.png](https://yummygyudon.notion.site/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F10896002-67a1-441c-9cea-b6f696faae26%2F36522594-3b8d-4995-b24e-fded2b1779e9%2Fimage.png?table=block&id=17779bee-8167-8007-92c1-c4b1fc0800cf&spaceId=10896002-67a1-441c-9cea-b6f696faae26&width=1420&userId=&cache=v2)
+ +### Features ⚙️ +- **번호 인증** + - 목적 기능에 따라 Type이 분류됩니다 (`REGISTER`/`CHANGE`/`SEARCH`) +- **회원 가입** +- **로그인** +- **가입 계정 플랫폼 조회** +- **JWKS Public Key 조회** + +
+ +### Environment Variables 🔑 +환경변수의 경우, `.env` 파일을 통해 관리되며 주입됩니다.
+주입된 `.env` 파일은 Docker 실행 시에 `--env-files` 옵션을 통해 어플리케이션에 적용됩니다.
+yaml 내 `${}` 정의된 변수명이 키 값이며 키 값에 해당하는 환경변수가 적용됩니다. + +`.env` 파일은 **Notion**과 **AWS S3**를 통해 관리됩니다.
+(자세한 내용은 플랫폼 팀 BE 구성원에게 문의 부탁드립니다.) + +
\ No newline at end of file From fd8dbdc315c2f2ba92fef69d2570919d057d39ef Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Sat, 11 Jan 2025 17:36:29 +0900 Subject: [PATCH 6/8] =?UTF-8?q?[DOCS]=20README=20-=20More=20About:Run=20Lo?= =?UTF-8?q?cally&Test=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 50 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 84e0b67..eb49e83 100644 --- a/README.md +++ b/README.md @@ -131,4 +131,53 @@ yaml 내 `${}` 정의된 변수명이 키 값이며 키 값에 해당하는 환 `.env` 파일은 **Notion**과 **AWS S3**를 통해 관리됩니다.
(자세한 내용은 플랫폼 팀 BE 구성원에게 문의 부탁드립니다.) -
\ No newline at end of file +
+ +### Run Locally 🏃‍♂️‍➡️ +> `local.env` 파일이 필요합니다. + +1. Clone the project +2. Open the project +3. Install/Refresh dependencies + ```shell + ./gradlew dependencies --refresh-dependencies + ``` +4. Move `.env` file to un-versioned package + ```ignorelang + # 현재 gitignore 적용된 path + **/src/main/resources/**/*.env + ``` +5. Set property files + - Apple Key file : `./src/main/resources/key` + - JWT Pem Key file : `./src/main/resources` +6. Run Application with `local.env` + - Itellij **사용** 시, 아래와 같이 실행합니다. + - 어플리케이션 실행 드롭다운 클릭 & [ **Edit Configurations...** ] 선택 + - [ Run ] 섹션의 [ **Modify options** ] 드룹다운 클릭 + - Operation System - [ **Environment variables** ] 선택 + ![스크린샷 2025-01-11 오후 5.28.47.png](..%2F..%2F%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202025-01-11%20%EC%98%A4%ED%9B%84%205.28.47.png) + - env 파일을 선택 + ![스크린샷 2025-01-11 오후 5.26.57.png](..%2F..%2F%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202025-01-11%20%EC%98%A4%ED%9B%84%205.26.57.png) + - Intellij **미사용** 시, 아래와 같이 실행합니다. + ```shell + # test 없이 build & Jar 생성 + ./gradlew clean build -x test + + # env 파일 내용을 실행 환경 변수(xargs)로 정의한 후, Jar 실행 + # `.env` path : 각자의 상황에 따른 반영 필요 + export $(cat ./src/main/resources/env/local.env | xargs) && java -jar ./build/libs/authentication.jar + ``` + +
+ +### Run Tests 🧪 +```bash +# Run All Test +./gradlew test + +# Run Specific Test Class +./gradlew test --tests "sopt.makers.**.XXXClass" + +# Run Specific Test Method +./gradlew test --tests "sopt.makers.**.XXXClass.XXXMethod" +``` From 4198abcbb343be86307d04e973bef7f59486c884 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Sat, 11 Jan 2025 18:13:56 +0900 Subject: [PATCH 7/8] =?UTF-8?q?[DOCS]=20README=20-=20More=20About:FAQ=20?= =?UTF-8?q?=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index eb49e83..8a09553 100644 --- a/README.md +++ b/README.md @@ -181,3 +181,25 @@ yaml 내 `${}` 정의된 변수명이 키 값이며 키 값에 해당하는 환 # Run Specific Test Method ./gradlew test --tests "sopt.makers.**.XXXClass.XXXMethod" ``` + +
+ +### FAQ + +#### ※ 왜 인증 서버를 따로 분리했나요? +- 기존 인증 체계의 경우, SOPT Playground 프로덕트 서버에서 전체 프로덕트의 인증을 수행했습니다. +- SOPT Playgorund 구성원은 프로덕트 외 관심사인 인증에 지나친 업무 부담, 소통 비용이 발생했습니다. +- SOPT Playground 구성원의 개발 생산성 저하는 물론 이 외 프로덕트 팀 구성원들 또한 의존적인 인증 기능 파악으로 인해 불필요한 소통 비용이 발생했습니다. +- 각 프로덕트팀은 각자의 서브 도메인(`**.sopt.org`) 환경에 맞춰 용이한 인증 정보 활용을 위해 SOPT Playground 인증 결과를 기반의 자체 인증 체계를 다시 구축했고 이로 인해 유저 정보가 여러 팀 DB에 중복되어 저장되는 문제가 발생했습니다. +- 전체 프로덕트팀 구성원들이 프로덕트에만 집중할 수 있도록 하며 유저 인증 기능 중복 구현, 데이터 중복 저장을 방지하기 위해 진행했습니다. + +
+ +#### ※ JWKS는 어떻게 활용하나요? +- 발급된 토큰을 복호화 및 검증해야 하는 전체 SOPT makers 프로덕트에서 사용합니다. +- 각 프로덕트 도메인의 클라이언트가 토큰을 담아 각 프로덕트 서버에 요청을 보낸 경우, 서버는 인증서버의 Public Key Set을 조회하여 Private 키와 함께 JWS 검증을 진행합니다. + +
+ +#### ※ 유저의 ID가 필요한데 어떻게 알아내나요? +- JWS 검증을 마친 이후, 해당 토큰을 복호화하여 추출한 Claim을 통해 얻어낼 수 있습니다. From 90a0b368d569f03a7c659c5ff6c0f7b7ca3223c8 Mon Sep 17 00:00:00 2001 From: yummygyudon Date: Sat, 11 Jan 2025 18:21:58 +0900 Subject: [PATCH 8/8] =?UTF-8?q?[MODIFY]=20=EC=B2=A8=EB=B6=80=20Image=20URL?= =?UTF-8?q?=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 8a09553..181fd2b 100644 --- a/README.md +++ b/README.md @@ -155,9 +155,9 @@ yaml 내 `${}` 정의된 변수명이 키 값이며 키 값에 해당하는 환 - 어플리케이션 실행 드롭다운 클릭 & [ **Edit Configurations...** ] 선택 - [ Run ] 섹션의 [ **Modify options** ] 드룹다운 클릭 - Operation System - [ **Environment variables** ] 선택 - ![스크린샷 2025-01-11 오후 5.28.47.png](..%2F..%2F%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202025-01-11%20%EC%98%A4%ED%9B%84%205.28.47.png) + ![run_application_with_png(1)](https://yummygyudon.notion.site/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F10896002-67a1-441c-9cea-b6f696faae26%2Fa3fd0f03-9fd2-4ab1-856f-c88867ecb88c%2F%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA_2025-01-11_%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE_5.28.47.png?table=block&id=17879bee-8167-801c-842d-e6c3e866f159&spaceId=10896002-67a1-441c-9cea-b6f696faae26&width=1420&userId=&cache=v2) - env 파일을 선택 - ![스크린샷 2025-01-11 오후 5.26.57.png](..%2F..%2F%EC%8A%A4%ED%81%AC%EB%A6%B0%EC%83%B7%202025-01-11%20%EC%98%A4%ED%9B%84%205.26.57.png) + ![run_application_with_png(2)](https://yummygyudon.notion.site/image/https%3A%2F%2Fprod-files-secure.s3.us-west-2.amazonaws.com%2F10896002-67a1-441c-9cea-b6f696faae26%2Fe3234953-e1c1-45a4-901b-cdff84fdba21%2F%25E1%2584%2589%25E1%2585%25B3%25E1%2584%258F%25E1%2585%25B3%25E1%2584%2585%25E1%2585%25B5%25E1%2586%25AB%25E1%2584%2589%25E1%2585%25A3%25E1%2586%25BA_2025-01-11_%25E1%2584%258B%25E1%2585%25A9%25E1%2584%2592%25E1%2585%25AE_5.26.57.png?table=block&id=17879bee-8167-80ea-8e53-d3e86e3f3dec&spaceId=10896002-67a1-441c-9cea-b6f696faae26&width=1420&userId=&cache=v2) - Intellij **미사용** 시, 아래와 같이 실행합니다. ```shell # test 없이 build & Jar 생성