Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 4 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,12 @@ out/


### custom ###
application-aws.yml
application-credentials.yml
#application-aws.yml
#application-credentials.yml
Secret.java
application-prod.yml
application*.tar
application-*.gpg
logs/
application-infra.yml
application-dev.yml
129 changes: 66 additions & 63 deletions build.gradle
Original file line number Diff line number Diff line change
@@ -1,96 +1,99 @@
plugins {
id 'org.springframework.boot' version '2.5.6'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
// querydsl
id "com.ewerk.gradle.plugins.querydsl" version "1.0.10"
id 'org.springframework.boot' version '2.5.6'
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
id 'java'
// querydsl
id "com.ewerk.gradle.plugins.querydsl" version "1.0.10"
}

group = 'com.sikhye'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '11'

configurations {
compileOnly {
extendsFrom annotationProcessor
}
compileOnly {
extendsFrom annotationProcessor
}
}

repositories {
mavenCentral()
mavenCentral()
}

dependencies {
// mysql DB
runtimeOnly ('mysql:mysql-connector-java') //mysql8
// mysql DB
runtimeOnly('mysql:mysql-connector-java') //mysql8

// spring batch
implementation 'org.springframework.boot:spring-boot-starter-batch'
testImplementation 'org.springframework.batch:spring-batch-test'
// spring batch
implementation 'org.springframework.boot:spring-boot-starter-batch'
testImplementation 'org.springframework.batch:spring-batch-test'

// spring jpa
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
// spring jpa
implementation 'org.springframework.boot:spring-boot-starter-data-jpa'

// spring template
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'
// spring template
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
implementation 'org.springframework.boot:spring-boot-starter-web'

// Bean Validation
implementation 'org.springframework.boot:spring-boot-starter-validation'
// Bean Validation
implementation 'org.springframework.boot:spring-boot-starter-validation'

// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
// Lombok
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'

// spring boot starter
testImplementation 'org.springframework.boot:spring-boot-starter-test'
// spring boot starter
testImplementation 'org.springframework.boot:spring-boot-starter-test'

// Security, Authentication(JWT Token)
implementation('org.springframework.boot:spring-boot-starter-security:2.5.4')
implementation group: 'io.jsonwebtoken', name: 'jjwt', version: '0.2'
implementation('org.springframework.boot:spring-boot-starter')
// Security, Authentication(JWT Token)
implementation('org.springframework.boot:spring-boot-starter-security:2.5.4')
implementation group: 'io.jsonwebtoken', name: 'jjwt', version: '0.2'
implementation('org.springframework.boot:spring-boot-starter')

// Spring Security for OAuth2)
implementation('org.springframework.boot:spring-boot-starter-oauth2-client')
implementation('org.springframework.boot:spring-boot-starter-mustache')
// Spring Security for OAuth2)
implementation('org.springframework.boot:spring-boot-starter-oauth2-client')
implementation('org.springframework.boot:spring-boot-starter-mustache')

// related to test
implementation('org.springframework.boot:spring-boot-devtools')
// related to test
implementation('org.springframework.boot:spring-boot-devtools')

// for Crawling
implementation('org.jsoup:jsoup:1.14.1')
// for Crawling
implementation('org.jsoup:jsoup:1.14.1')

// p6spy
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.8'
// p6spy
implementation 'com.github.gavlyukovskiy:p6spy-spring-boot-starter:1.5.8'


// querydsl
implementation 'com.querydsl:querydsl-jpa'
// querydsl
implementation 'com.querydsl:querydsl-jpa'

// AWS S3
implementation platform('com.amazonaws:aws-java-sdk-bom:1.11.1000')
implementation 'com.amazonaws:aws-java-sdk-s3:1.12.111'
// AWS S3
implementation platform('com.amazonaws:aws-java-sdk-bom:1.11.1000')
implementation 'com.amazonaws:aws-java-sdk-s3:1.12.111'

// AWS cloud starter aws
implementation('org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE')
// AWS cloud starter aws
implementation('org.springframework.cloud:spring-cloud-starter-aws:2.2.6.RELEASE')

// index.html로 forwarding 하기 위함
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
// index.html로 forwarding 하기 위함
implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'

// @ConfigureProperties를 사용하기 위해 추가
// configure 파일을 읽어들이기 위함
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"
// @ConfigureProperties를 사용하기 위해 추가
// configure 파일을 읽어들이기 위함
annotationProcessor "org.springframework.boot:spring-boot-configuration-processor"

// 이메일 인증
implementation 'org.springframework.boot:spring-boot-starter-mail'
// 이메일 인증
implementation 'org.springframework.boot:spring-boot-starter-mail'

// spring redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'
// spring redis
implementation 'org.springframework.boot:spring-boot-starter-data-redis'

// 로그 처리 시 조건 추가
implementation 'org.codehaus.janino:janino:3.0.12'

}

test {
useJUnitPlatform()
useJUnitPlatform()
}

// ==========================================
Expand All @@ -100,21 +103,21 @@ test {
def querydslDir = "$buildDir/generated/querydsl"

querydsl {
jpa = true
querydslSourcesDir = querydslDir
jpa = true
querydslSourcesDir = querydslDir
}
sourceSets {
main.java.srcDir querydslDir
main.java.srcDir querydslDir
}
configurations {
querydsl.extendsFrom compileClasspath
querydsl.extendsFrom compileClasspath
}
compileQuerydsl {
options.annotationProcessorPath = configurations.querydsl
options.annotationProcessorPath = configurations.querydsl
}
//querydsl 추가 끝
/** * comileQuerydsl.doFirst 추가 */
compileQuerydsl.doFirst {
if(file(querydslDir).exists() )
delete(file(querydslDir))
if (file(querydslDir).exists())
delete(file(querydslDir))
}
2 changes: 1 addition & 1 deletion chabak-deploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -24,4 +24,4 @@ fi
echo "> $JAR_PATH 배포"
#nohup java -jar $JAR_PATH > /dev/null 2> /dev/null < /dev/null &
#code deploy에 출력이 되기 때문에 nohup.out 파일을 사용해야 한다.
nohup java -jar $JAR_PATH > $REPOSITORY/nohup.out 2>&1 &
nohup java -jar -Dspring.profiles.active=prod $JAR_PATH > $REPOSITORY/nohup.out 2>&1 &
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재 스크립트 시나리오, 항상 prod 을 가지고 있는데요,
dev 의 경우에는 배포를 따로할까요?

보통 외부에서 환경에 대한 변수 dev, prod 등을 받고 내부에서 이것을 결정하게 하는 방법을 사용하고 있는데요,
지금의 배포 환경을 점검해보고 변경이 좋다면 변경하면 좋을거 같습니다.

5 changes: 5 additions & 0 deletions src/main/java/com/sikhye/chabak/base/entity/BaseRole.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package com.sikhye.chabak.base.entity;

public enum BaseRole {
ROLE_USER, ROLE_ADMIN
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package com.sikhye.chabak.interceptor;

import static com.sikhye.chabak.base.BaseResponseStatus.*;
import static com.sikhye.chabak.base.entity.BaseRole.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import com.sikhye.chabak.base.entity.BaseRole;
import com.sikhye.chabak.base.exception.BaseException;
import com.sikhye.chabak.utils.JwtTokenService;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class JwtAdminInterceptor implements HandlerInterceptor {

private final JwtTokenService jwtTokenService;

public JwtAdminInterceptor(JwtTokenService jwtTokenService) {
this.jwtTokenService = jwtTokenService;
}

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws
Exception {

String requestURI = request.getRequestURI();

// places에서 GET 방식이라면 Admin 기능이 아닌 Member도 사용 가능
if (request.getMethod().equals("GET")) {
return true;
}

log.info("인증 체크 인터셉터 실행 {}", requestURI);

// 관리자 권한이 아닌 경우 api 요청 불가
BaseRole memberRole = jwtTokenService.getMemberRole();

if (!memberRole.equals(ROLE_ADMIN)) {
throw new BaseException(INVALID_USER_JWT);
}

return true;

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package com.sikhye.chabak.interceptor;

import static com.sikhye.chabak.base.BaseResponseStatus.*;
import static com.sikhye.chabak.utils.JwtValue.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.web.servlet.HandlerInterceptor;

import com.sikhye.chabak.base.exception.BaseException;

import lombok.extern.slf4j.Slf4j;

@Slf4j
@Component
public class JwtMemberInterceptor implements HandlerInterceptor {

@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response,
Object handler) throws Exception {

String requestURI = request.getRequestURI();
log.info("토큰명 : {}", X_ACCESS_TOKEN.toString());
String accessToken = request.getHeader(X_ACCESS_TOKEN.toString());

log.info("인증 체크 인터셉터 실행 {}", requestURI);

if (accessToken == null || accessToken.isBlank()) {
log.info("미인증 JWT 요청");
throw new BaseException(EMPTY_JWT);
}

return true;
}

}
40 changes: 40 additions & 0 deletions src/main/java/com/sikhye/chabak/interceptor/WebConfig.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package com.sikhye.chabak.interceptor;

import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

@Configuration
public class WebConfig implements WebMvcConfigurer {

private final JwtMemberInterceptor jwtMemberInterceptor;
private final JwtAdminInterceptor jwtAdminInterceptor;

public WebConfig(JwtMemberInterceptor jwtMemberInterceptor, JwtAdminInterceptor jwtAdminInterceptor) {
this.jwtMemberInterceptor = jwtMemberInterceptor;
this.jwtAdminInterceptor = jwtAdminInterceptor;
}

// 인터셉터 등록
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(jwtMemberInterceptor) // 인터셉터 등록
.order(1) // 인터셉터 호출 우선순위
.addPathPatterns("/**") // 인터셉터 적용할 URI 패턴
.excludePathPatterns("/error", "/members/**", "/auth/**"); // 인터셉터에서 제외할 URI 패턴

registry.addInterceptor(jwtAdminInterceptor)
.order(2)
.addPathPatterns("/places/**")
.excludePathPatterns("/places/comments/**");
}

@Override
public void addCorsMappings(CorsRegistry registry) {
registry.addMapping("/**")
.allowedOrigins("http://localhost:3000")
.allowedMethods("GET", "POST", "OPTIONS", "PUT", "PATCH");
}

}
Loading