diff --git a/.github/workflows/cd.yml b/.github/workflows/cd.yml index f472036..c38bb50 100644 --- a/.github/workflows/cd.yml +++ b/.github/workflows/cd.yml @@ -1,64 +1,64 @@ -name: Server CD - -on: - push: - branches: - - main - -jobs: - build: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: Set up JDK 18 - uses: actions/setup-java@v4 - with: - java-version: "18" - distribution: "adopt" - - - name: Run chmod to make gradlew executable - run: chmod +x ./gradlew - - - name: Add application.properties - run: | - mkdir -p ./src/main/resources - touch ./src/main/resources/application.properties - echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.properties - cat ./src/main/resources/application.properties - - - name: Build with Gradle - run: ./gradlew clean build - - - name: Build docker image - run: | - sudo chmod 666 /var/run/docker.sock - docker buildx build --no-cache --platform linux/amd64 -t ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_IMAGE_NAME }}:latest -f ./Dockerfile . - - - name: Login to Docker Hub - uses: docker/login-action@v2 - with: - username: ${{ secrets.DOCKERHUB_USERNAME }} - password: ${{ secrets.DOCKERHUB_TOKEN }} - - - name: Publish to Docker Hub - run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_IMAGE_NAME }}:latest - - - name: Connect to WAS & Execute Application - uses: appleboy/ssh-action@v0.1.6 - with: - host: ${{ secrets.SERVER_HOST }} - username: ${{ secrets.SERVER_USERNAME }} - key: ${{ secrets.SERVER_KEY }} - port: ${{ secrets.SERVER_PORT }} - script: | - sudo chmod 666 /var/run/docker.sock - sudo chmod +x /usr/local/bin/docker-compose - cd /home/${{ secrets.SERVER_USERNAME }} - sudo docker-compose stop - sudo docker-compose rm -f - sudo docker-compose pull ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_IMAGE_NAME }}:latest - docker-compose up -d - sudo docker system prune -f - echo "끝" +#name: Server CD +# +#on: +# push: +# branches: +# - main +# +#jobs: +# build: +# runs-on: ubuntu-latest +# +# steps: +# - uses: actions/checkout@v4 +# +# - name: Set up JDK 18 +# uses: actions/setup-java@v4 +# with: +# java-version: "18" +# distribution: "adopt" +# +# - name: Run chmod to make gradlew executable +# run: chmod +x ./gradlew +# +# - name: Add application.properties +# run: | +# mkdir -p ./src/main/resources +# touch ./src/main/resources/application.properties +# echo "${{ secrets.APPLICATION }}" > ./src/main/resources/application.properties +# cat ./src/main/resources/application.properties +# +# - name: Build with Gradle +# run: ./gradlew clean build +# +# - name: Build docker image +# run: | +# sudo chmod 666 /var/run/docker.sock +# docker buildx build --no-cache --platform linux/amd64 -t ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_IMAGE_NAME }}:latest -f ./Dockerfile . +# +# - name: Login to Docker Hub +# uses: docker/login-action@v2 +# with: +# username: ${{ secrets.DOCKERHUB_USERNAME }} +# password: ${{ secrets.DOCKERHUB_TOKEN }} +# +# - name: Publish to Docker Hub +# run: docker push ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_IMAGE_NAME }}:latest +# +# - name: Connect to WAS & Execute Application +# uses: appleboy/ssh-action@v0.1.6 +# with: +# host: ${{ secrets.SERVER_HOST }} +# username: ${{ secrets.SERVER_USERNAME }} +# key: ${{ secrets.SERVER_KEY }} +# port: ${{ secrets.SERVER_PORT }} +# script: | +# sudo chmod 666 /var/run/docker.sock +# sudo chmod +x /usr/local/bin/docker-compose +# cd /home/${{ secrets.SERVER_USERNAME }} +# sudo docker-compose stop +# sudo docker-compose rm -f +# sudo docker-compose pull ${{ secrets.DOCKERHUB_USERNAME }}/${{ secrets.DOCKERHUB_IMAGE_NAME }}:latest +# docker-compose up -d +# sudo docker system prune -f +# echo "끝" diff --git a/src/main/java/oauth/auth/JwtService.java b/src/main/java/oauth/auth/JwtService.java index 7caae08..a01b23f 100644 --- a/src/main/java/oauth/auth/JwtService.java +++ b/src/main/java/oauth/auth/JwtService.java @@ -49,20 +49,21 @@ public String createRefreshToken() { .compact(); } - public String decodeAccessToken(String token) throws Exception{ - try { + public String decodeAccessToken(String token) { + //TODO: validation 여기서 안할 때 문제 없을까 생각해봐야함 +// try { Claims claims = Jwts.parser() .setSigningKey(secretKey) .parseClaimsJws(token) .getBody(); - return claims.getSubject(); - } catch (ExpiredJwtException e) { - throw e; - } + return claims.getSubject() != null ? claims.getSubject() : null; +// } catch (ExpiredJwtException e) { +// throw e; +// } } - public boolean isValidToken(String token) throws Exception { + public boolean isValidToken(String token) { try { Jwts.parserBuilder().build().parseClaimsJws(token); diff --git a/src/main/java/oauth/config/FilterConfig.java b/src/main/java/oauth/config/FilterConfig.java new file mode 100644 index 0000000..627c81d --- /dev/null +++ b/src/main/java/oauth/config/FilterConfig.java @@ -0,0 +1,19 @@ +package oauth.config; + +import oauth.auth.JwtService; +import org.springframework.boot.web.servlet.FilterRegistrationBean; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class FilterConfig { + + @Bean + public FilterRegistrationBean accessTokenValidationFilter(JwtService jwtService) { + FilterRegistrationBean registrationBean = new FilterRegistrationBean<>(); + registrationBean.setFilter(new TokenValidationFilter(jwtService)); + registrationBean.addUrlPatterns("/users/*"); // 필터를 적용할 URL 패턴 설정 + return registrationBean; + } +} + diff --git a/src/main/java/oauth/config/TokenValidationFilter.java b/src/main/java/oauth/config/TokenValidationFilter.java new file mode 100644 index 0000000..5c04c2d --- /dev/null +++ b/src/main/java/oauth/config/TokenValidationFilter.java @@ -0,0 +1,65 @@ +package oauth.config; + +import jakarta.servlet.Filter; +import jakarta.servlet.FilterChain; +import jakarta.servlet.FilterConfig; +import jakarta.servlet.ServletException; +import jakarta.servlet.ServletRequest; +import jakarta.servlet.ServletResponse; +import jakarta.servlet.http.Cookie; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import oauth.auth.JwtService; + +import java.io.IOException; +import java.util.Arrays; + +@RequiredArgsConstructor +public class TokenValidationFilter implements Filter { + + private final JwtService jwtService; + + @Override + public void init(FilterConfig filterConfig) throws ServletException { + // 필터 초기화 작업이 필요하면 여기에 작성 + } + + @Override + public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { + + HttpServletRequest httpRequest = (HttpServletRequest) request; + HttpServletResponse httpResponse = (HttpServletResponse) response; + + // 쿠키에서 accessToken 가져오기 + Cookie[] cookies = httpRequest.getCookies(); + String accessToken = null; + + if (cookies != null) { + accessToken = Arrays.stream(cookies) + .filter(cookie -> "skt".equals(cookie.getName())) + .map(Cookie::getValue) + .findFirst() + .orElse(null); + } + + // 토큰이 존재하면 유효성 검사 수행 + if (accessToken != null && jwtService.isValidToken(accessToken)) { + String userId = jwtService.decodeAccessToken(accessToken); + + // 유효한 토큰인 경우 요청을 계속 처리 + if (userId != null) { + //TODO: destory에 뭘 넣어야 하는거지? + return; + } + } + + // 유효하지 않은 토큰인 경우 401 에러 반환 + httpResponse.sendError(HttpServletResponse.SC_UNAUTHORIZED, "Invalid access token"); + } + + @Override + public void destroy() { + // 필터 종료 작업이 필요하면 여기에 작성 + } +}