diff --git a/.github/workflows/dev_cicd.yml b/.github/workflows/dev_cicd.yml
new file mode 100644
index 0000000..68a375b
--- /dev/null
+++ b/.github/workflows/dev_cicd.yml
@@ -0,0 +1,55 @@
+name: Dev CI/CD
+
+on:
+ push:
+ branches:
+ - develop
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+
+ - name: Set up JDK 17
+ uses: actions/setup-java@v3
+ with:
+ distribution: 'corretto'
+ java-version: '17'
+
+ - name: Grant execute permission for gradlew
+ run: chmod +x gradlew
+
+ - name: Build with Gradle
+ run: ./gradlew clean build
+ env:
+ SPRING_PROFILE: dev
+ JWT_SECRET: ${{ secrets.JWT_SECRET }}
+ DB_URL: ${{ secrets.DB_URL }}
+ DB_USERNAME: ${{ secrets.DB_USERNAME }}
+ DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
+ REDIS_URL: ${{ secrets.REDIS_URL }}
+ REDIS_PORT: ${{ secrets.REDIS_PORT }}
+
+ - name: Get current time
+ uses: josStorer/get-current-time@v2.0.2
+ id: current-time
+ with:
+ format: YYYY-MM-DDTHH-mm-ss
+ utcOffset: "+09:00"
+
+ - name: Set artifact
+ run: echo "artifact=$(ls ./build/libs)" >> $GITHUB_ENV
+
+ - name: Beanstalk Deploy
+ uses: einaregilsson/beanstalk-deploy@v20
+ with:
+ aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ application_name: jwt-dev
+ environment_name: jwt-dev-env
+ version_label: github-action-${{steps.current-time.outputs.formattedTime}}
+ region: ap-northeast-2
+ deployment_package: ./build/libs/${{env.artifact}}
diff --git a/.github/workflows/release_cicd.yml b/.github/workflows/release_cicd.yml
new file mode 100644
index 0000000..d109e41
--- /dev/null
+++ b/.github/workflows/release_cicd.yml
@@ -0,0 +1,55 @@
+name: Release CI/CD
+
+on:
+ push:
+ branches:
+ - main
+
+jobs:
+ build:
+ runs-on: ubuntu-latest
+
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v3
+
+ - name: Set up JDK 17
+ uses: actions/setup-java@v3
+ with:
+ distribution: 'corretto'
+ java-version: '17'
+
+ - name: Grant execute permission for gradlew
+ run: chmod +x gradlew
+
+ - name: Build with Gradle
+ run: ./gradlew clean build
+ env:
+ SPRING_PROFILE: release
+ JWT_SECRET: ${{ secrets.JWT_SECRET }}
+ DB_URL: ${{ secrets.DB_URL }}
+ DB_USERNAME: ${{ secrets.DB_USERNAME }}
+ DB_PASSWORD: ${{ secrets.DB_PASSWORD }}
+ REDIS_URL: ${{ secrets.REDIS_URL }}
+ REDIS_PORT: ${{ secrets.REDIS_PORT }}
+
+ - name: Get current time
+ uses: josStorer/get-current-time@v2.0.2
+ id: current-time
+ with:
+ format: YYYY-MM-DDTHH-mm-ss
+ utcOffset: "+09:00"
+
+ - name: Set artifact
+ run: echo "artifact=$(ls ./build/libs)" >> $GITHUB_ENV
+
+ - name: Beanstalk Deploy
+ uses: einaregilsson/beanstalk-deploy@v20
+ with:
+ aws_access_key: ${{ secrets.AWS_ACCESS_KEY_ID }}
+ aws_secret_key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
+ application_name: jwt-release
+ environment_name: jwt-release-env
+ version_label: github-action-${{steps.current-time.outputs.formattedTime}}
+ region: ap-northeast-2
+ deployment_package: ./build/libs/${{env.artifact}}
diff --git a/.gitignore b/.gitignore
index c5d6ec2..05a74ea 100644
--- a/.gitignore
+++ b/.gitignore
@@ -483,8 +483,4 @@ gradle-app.setting
# Java heap dump
*.hprof
-# yml files
-application-*.yml
-!application-local.yml
-
# End of https://www.toptal.com/developers/gitignore/api/macos
\ No newline at end of file
diff --git a/README.md b/README.md
index e350c6e..70dfc9b 100644
--- a/README.md
+++ b/README.md
@@ -1,3 +1,29 @@
# Spring Boot JWT
> Spring Boot, Spring Security를 이용한 JWT 인증·인가 서버 템플릿
+
+## ⚒️ Tech Stack
+
+* #### Backend
+
+
+
+
+
+* #### Build Tool
+
+
+* #### DBMS
+
+
+* #### CI/CD
+
+
+
+
+
+* #### Deploy
+
+
+
+
diff --git a/build.gradle b/build.gradle
index 507f8e9..051bc72 100644
--- a/build.gradle
+++ b/build.gradle
@@ -5,7 +5,7 @@ plugins {
}
group = 'com.hyunmin'
-version = '0.0.1-SNAPSHOT'
+version = '1.0.0'
java {
toolchain {
@@ -13,6 +13,10 @@ java {
}
}
+jar {
+ enabled = false
+}
+
configurations {
compileOnly {
extendsFrom annotationProcessor
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..5bae62c
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,8 @@
+version: '3'
+
+services:
+ redis:
+ image: redis:latest
+ container_name: jwt-redis
+ ports:
+ - "6379:6379"
diff --git a/src/main/java/com/hyunmin/jwt/global/exception/code/ErrorCode.java b/src/main/java/com/hyunmin/jwt/global/exception/code/ErrorCode.java
index a38134d..4709157 100644
--- a/src/main/java/com/hyunmin/jwt/global/exception/code/ErrorCode.java
+++ b/src/main/java/com/hyunmin/jwt/global/exception/code/ErrorCode.java
@@ -30,7 +30,11 @@ public enum ErrorCode {
// Member Errors
MEMBER_FORBIDDEN(403, "MEMBER001", "사용자 권한이 없습니다."),
- MEMBER_NOT_FOUND(404, "MEMBER002", "해당 사용자가 없습니다.");
+ MEMBER_NOT_FOUND(404, "MEMBER002", "해당 사용자가 없습니다."),
+
+ // Redis Errors
+ REDIS_CONNECTION_FAILURE(500, "REDIS001", "Redis 서버에 연결할 수 없습니다."),
+ REDIS_SYSTEM_EXCEPTION(500, "REDIS002", "Redis 시스템 예외가 발생했습니다.");
private final int value;
private final String code;
diff --git a/src/main/java/com/hyunmin/jwt/global/exception/handler/GeneralExceptionHandler.java b/src/main/java/com/hyunmin/jwt/global/exception/handler/GeneralExceptionHandler.java
index 9b043b8..a215c79 100644
--- a/src/main/java/com/hyunmin/jwt/global/exception/handler/GeneralExceptionHandler.java
+++ b/src/main/java/com/hyunmin/jwt/global/exception/handler/GeneralExceptionHandler.java
@@ -6,6 +6,8 @@
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.MessageSourceResolvable;
import org.springframework.dao.DataIntegrityViolationException;
+import org.springframework.data.redis.RedisConnectionFailureException;
+import org.springframework.data.redis.RedisSystemException;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
@@ -51,6 +53,22 @@ protected ResponseEntity> handleHandlerMethodValidationExcep
return ErrorResponse.handle(errorCode);
}
+ // Redis 서버 연결 실패(RedisConnectionFailureException) 처리 메서드
+ @ExceptionHandler(RedisConnectionFailureException.class)
+ protected ResponseEntity> handleRedisConnectionFailureException(RedisConnectionFailureException ex) {
+ log.warn("[WARNING] {} : {}", ex.getClass(), ex.getMessage());
+ ErrorCode errorCode = ErrorCode.REDIS_CONNECTION_FAILURE;
+ return ErrorResponse.handle(errorCode);
+ }
+
+ // Redis 서버 오류(REDIS_SYSTEM_EXCEPTION) 처리 메서드
+ @ExceptionHandler(RedisSystemException.class)
+ protected ResponseEntity> handleRedisSystemException(RedisSystemException ex) {
+ log.warn("[WARNING] {} : {}", ex.getClass(), ex.getMessage());
+ ErrorCode errorCode = ErrorCode.REDIS_SYSTEM_EXCEPTION;
+ return ErrorResponse.handle(errorCode);
+ }
+
// 기타 모든 예외(Exception) 처리 메서드
@ExceptionHandler(Exception.class)
protected ResponseEntity> handleException(Exception ex) {
diff --git a/src/main/java/com/hyunmin/jwt/global/security/config/SecurityConfig.java b/src/main/java/com/hyunmin/jwt/global/security/config/SecurityConfig.java
index 6de576d..4285945 100644
--- a/src/main/java/com/hyunmin/jwt/global/security/config/SecurityConfig.java
+++ b/src/main/java/com/hyunmin/jwt/global/security/config/SecurityConfig.java
@@ -6,7 +6,6 @@
import com.hyunmin.jwt.global.security.handler.JwtAuthenticationEntryPoint;
import com.hyunmin.jwt.global.security.provider.JwtTokenProvider;
import lombok.RequiredArgsConstructor;
-import org.springframework.boot.autoconfigure.security.servlet.PathRequest;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
@@ -51,8 +50,7 @@ public SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
// 경로별 인가 작업
http.authorizeHttpRequests(authorize -> authorize
// H2 콘솔과 Swagger UI 및 API 문서에 대한 접근 허용
- .requestMatchers(PathRequest.toH2Console()).permitAll()
- .requestMatchers("/swagger-ui/**", "/v3/api-docs/**").permitAll()
+ .requestMatchers("/h2-console/**", "/swagger-ui/**", "/v3/api-docs/**").permitAll()
// API 계정 관련 요청에 대한 접근 허용
.requestMatchers("/api/v1/accounts/**").permitAll()
// 전체 사용자 정보 조회 API 관리자 권한만 접근 허용
diff --git a/src/main/resources/application-dev.yml b/src/main/resources/application-dev.yml
new file mode 100644
index 0000000..cb9ee70
--- /dev/null
+++ b/src/main/resources/application-dev.yml
@@ -0,0 +1,21 @@
+spring:
+ datasource:
+ url: ${DB_URL}
+ username: ${DB_USERNAME}
+ password: ${DB_PASSWORD}
+ driver-class-name: com.mysql.cj.jdbc.Driver
+
+ data:
+ redis:
+ host: ${REDIS_URL}
+ port: ${REDIS_PORT}
+
+ jpa:
+ properties:
+ hibernate:
+ dialect: org.hibernate.dialect.MySQLDialect
+ show_sql: true
+ format_sql: true
+
+ hibernate:
+ ddl-auto: update
diff --git a/src/main/resources/application-local.yml b/src/main/resources/application-local.yml
index 610f140..ef5ede2 100644
--- a/src/main/resources/application-local.yml
+++ b/src/main/resources/application-local.yml
@@ -5,14 +5,15 @@ spring:
password:
driver-class-name: org.h2.Driver
+ h2:
+ console:
+ enabled: true
+
jpa:
- hibernate:
- ddl-auto: update
properties:
hibernate:
show_sql: true
format_sql: true
- h2:
- console:
- enabled: true
+ hibernate:
+ ddl-auto: update
diff --git a/src/main/resources/application-release.yml b/src/main/resources/application-release.yml
new file mode 100644
index 0000000..8fdd59b
--- /dev/null
+++ b/src/main/resources/application-release.yml
@@ -0,0 +1,21 @@
+spring:
+ datasource:
+ url: ${DB_URL}
+ username: ${DB_USERNAME}
+ password: ${DB_PASSWORD}
+ driver-class-name: com.mysql.cj.jdbc.Driver
+
+ data:
+ redis:
+ host: ${REDIS_URL}
+ port: ${REDIS_PORT}
+
+ jpa:
+ properties:
+ hibernate:
+ dialect: org.hibernate.dialect.MySQLDialect
+ show_sql: true
+ format_sql: true
+
+ hibernate:
+ ddl-auto: none
diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml
index 055870b..0029987 100644
--- a/src/main/resources/application.yml
+++ b/src/main/resources/application.yml
@@ -1,9 +1,9 @@
spring:
profiles:
- active: local
+ active: ${SPRING_PROFILE:local}
jwt:
- secret: ${JWT_SECRET}
+ secret: ${JWT_SECRET:secret}
token:
access-expiration-time: 1800 # 30 minutes
refresh-expiration-time: 1209600 # 14 days