diff --git a/.github/workflows/cicd.yml b/.github/workflows/cicd.yml index 9c7af7d..9286bc8 100644 --- a/.github/workflows/cicd.yml +++ b/.github/workflows/cicd.yml @@ -40,16 +40,6 @@ jobs: # script의 내용은 도커의 기존 프로세스들을 제거하고, docker repo로부터 방금 위에서 push한 내용을 pull 받아 실행하는 것입니다. # 실행 시, docker-compose를 사용합니다. steps: -# - name: ✔️ send docker-compose.yml to EC2 server -# uses: appleboy/scp-action@v0.1.3 -# with: -# username: ec2-user -# host: ${{ secrets.HOST }} -# key: ${{ secrets.KEY }} -# port: 22 -# source: "dev/docker-compose.dev.yml" -# target: "/home/ec2-user" - - name: Deploy to server uses: appleboy/ssh-action@master id: deploy @@ -62,7 +52,6 @@ jobs: docker rm -f $(docker ps -qa) # 기존에 실행되고 있는 도커 프로세스들을 제거합니다. docker rmi $(docker images -q) # 기존에 존재하는 도커 이미지들을 제거합니다. docker image prune -f # 사용하지 않는 도커 이미지들을 제거합니다. + docker-compose up -d # mysql 개발용 컨테이너를 실행합니다. docker pull ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.sha }} - docker run -d -p 80:8080 ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.sha }} - #docker-compose -f /home/ec2-user/docker-compose.dev.yml up -d - + docker run -d -p 80:8080 ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.sha }} -e SPRING_PROFILES_ACTIVE=dev -e KAKAO_CLIENT_SECRET=${{ secrets.KAKAO_CLIENT_SECRET }} -e NAVER_CLIENT_SECRET=${{ secrets.NAVER_CLIENT_SECRET }} -e KAKAO_REDIRECT_URI=${{ secrets.KAKAO_REDIRECT_URI }} diff --git a/dev/docker-compose.dev.yml b/dev/docker-compose.dev.yml deleted file mode 100644 index 98b6ae3..0000000 --- a/dev/docker-compose.dev.yml +++ /dev/null @@ -1,30 +0,0 @@ -version: '3' - # 실행명령어 - # docker-compose -f ./docker-compose.dev.yml up -services: - zzansuni-mysql: - image: mysql - restart: always - volumes: - - ./mysql-data:/var/lib/mysql - ports: - - "3306:3306" - environment: - MYSQL_DATABASE: zzansuni - MYSQL_ROOT_PASSWORD: root - zzanuni-spring: - image: ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKER_REPOSITORY }}:${{ github.sha }} - restart: always - ports: - - "80:8080" - depends_on: - - zzansuni-mysql - environment: - SPRING_PROFILES_ACTIVE: dev - JWT_SECRET: 4099a46b-39db-4860-a61b-2ae76ea24c43 - KAKAO_CLIENT_ID: ${{ secrets.KAKAO_CLIENT_ID }} - KAKAO_CLIENT_SECRET: ${{ secrets.KAKAO_CLIENT_SECRET }} - KAKAO_REDIRECT_URI: ${{ secrets.KAKAO_REDIRECT_URI }} - NAVER_CLIENT_ID: ${{ secrets.NAVER_CLIENT_ID }} - NAVER_CLIENT_SECRET: ${{ secrets.NAVER_CLIENT_SECRET }} - diff --git a/docker-compose.dev.yml b/docker-compose.dev.yml new file mode 100644 index 0000000..9987dd1 --- /dev/null +++ b/docker-compose.dev.yml @@ -0,0 +1,14 @@ +version: '3' + # 실행명령어 + # docker-compose -f ./docker-compose.dev.yml up +services: + zzansuni-mysql: + image: mysql + restart: always + volumes: + - ./mysql-data:/var/lib/mysql + ports: + - "3306:3306" + environment: + MYSQL_DATABASE: zzansuni + MYSQL_ROOT_PASSWORD: root \ No newline at end of file diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/auth/AuthController.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/auth/AuthController.java index 636f121..3cf4cef 100644 --- a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/auth/AuthController.java +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/auth/AuthController.java @@ -12,6 +12,7 @@ import org.springframework.data.util.Pair; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestHeader; import org.springframework.web.bind.annotation.RestController; @Tag(name = "auth", description = "인증 관련 API") @@ -44,6 +45,20 @@ public ApiResponse login(@RequestBody @Valid AuthReq.Emai return ApiResponse.success(response); } + @Operation(summary = "액세스 토큰 재발급", description = "리프레시 토큰을 이용하여 액세스 토큰을 재발급한다.") + @PostMapping("/api/auth/refresh") + public ApiResponse refresh( + @RequestHeader("Authorization") String authorization + ) { + if(authorization == null || !authorization.startsWith("Bearer ")) { + throw new IllegalArgumentException("Bearer 토큰이 필요합니다."); + } + String rawToken = authorization.substring("Bearer ".length()); + String accessToken = authService.reissueToken(rawToken); + var response = AuthRes.AccessTokenResponse.of(accessToken); + return ApiResponse.success(response); + } + @Operation(summary = "로그아웃", description = "로그아웃한다.") @PostMapping("/api/auth/logout") public ApiResponse logout() { diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/auth/AuthRes.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/auth/AuthRes.java index c83b62b..073d012 100644 --- a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/auth/AuthRes.java +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/controller/auth/AuthRes.java @@ -21,4 +21,15 @@ public static LoginResponse from(JwtToken jwtToken, UserModel userModel) { .build(); } } + + @Builder + public record AccessTokenResponse( + String accessToken + ) { + public static AccessTokenResponse of(String accessToken) { + return AccessTokenResponse.builder() + .accessToken(accessToken) + .build(); + } + } } diff --git a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/auth/AuthService.java b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/auth/AuthService.java index ae87ad0..e496c2c 100644 --- a/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/auth/AuthService.java +++ b/zzansuni-api-server/app/src/main/java/org/haedal/zzansuni/domain/auth/AuthService.java @@ -100,4 +100,14 @@ public Pair login(String email, String password) { UserModel userModel = UserModel.from(user); return Pair.of(jwtToken, userModel); } + + public String reissueToken(String rawToken) { + if(!jwtUtils.validateToken(rawToken)){ + throw new IllegalArgumentException("RefreshToken이 유효하지 않습니다."); + } + JwtToken.ValidToken token = JwtToken.ValidToken.of(rawToken); + jwtUtils.reissueAccessToken(token); + + return jwtUtils.reissueAccessToken(JwtToken.ValidToken.of(rawToken)); + } } diff --git a/zzansuni-api-server/app/src/main/resources/application.yml b/zzansuni-api-server/app/src/main/resources/application.yml index ccdc370..0dda845 100644 --- a/zzansuni-api-server/app/src/main/resources/application.yml +++ b/zzansuni-api-server/app/src/main/resources/application.yml @@ -25,7 +25,7 @@ springdoc: default-consumes-media-type: application/json;charset=UTF-8 default-produces-media-type: application/json;charset=UTF-8 jwt: - secret: 4099a46b-39db-4860-a61b-2ae76ea24c43 + secret: ${JWT_SECRET:4099a46b-39db-4860-a61b-2ae76ea24c43} access-token-expire-time: 1800000 # 30 minutes refresh-token-expire-time: 2592000000 # 30 days #cloud: @@ -51,8 +51,6 @@ spring: hibernate: dialect: org.hibernate.dialect.MySQL8Dialect h2.console.enabled: false -jwt: - secret: ${JWT_SECRET} kakao: client-id: c959f4526a0df321dff0a8636fec3428 client-secret: ${KAKAO_CLIENT_SECRET}