diff --git a/src/main/java/com/example/healthylife/config/PasswordEncoderConfig.java b/src/main/java/com/example/healthylife/config/PasswordEncoderConfig.java index 6006804..c8b1e98 100644 --- a/src/main/java/com/example/healthylife/config/PasswordEncoderConfig.java +++ b/src/main/java/com/example/healthylife/config/PasswordEncoderConfig.java @@ -4,13 +4,12 @@ import org.springframework.context.annotation.Configuration; import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; + @Configuration public class PasswordEncoderConfig { - //비밀번호 암호화 작업 @Bean public PasswordEncoder passwordEncoder() { return new BCryptPasswordEncoder(); } } - diff --git a/src/main/java/com/example/healthylife/config/SecurityConfig.java b/src/main/java/com/example/healthylife/config/SecurityConfig.java index 58440a7..fcac2a3 100644 --- a/src/main/java/com/example/healthylife/config/SecurityConfig.java +++ b/src/main/java/com/example/healthylife/config/SecurityConfig.java @@ -2,13 +2,14 @@ import com.example.healthylife.config.jwt.JwtAuthenticationFilter; import com.example.healthylife.config.jwt.JwtUtil; +import com.example.healthylife.config.security.MyUserDetailsService; import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Bean; import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.dao.DaoAuthenticationProvider; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter; -import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; import org.springframework.security.crypto.password.PasswordEncoder; import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; @@ -17,6 +18,8 @@ public class SecurityConfig extends WebSecurityConfigurerAdapter { private final JwtUtil jwtUtil; + private final MyUserDetailsService myUserDetailsService; + private final PasswordEncoder passwordEncoder; @Override protected void configure(HttpSecurity http) throws Exception { @@ -32,6 +35,16 @@ protected void configure(HttpSecurity http) throws Exception { @Bean @Override public AuthenticationManager authenticationManagerBean() throws Exception { + // AuthenticationManager를 빈으로 등록하여 인증 관련 작업을 수행할 수 있도록 설정 return super.authenticationManagerBean(); } + + @Bean + public DaoAuthenticationProvider authenticationProvider() { + // DaoAuthenticationProvider를 설정하여 사용자 세부 정보와 비밀번호 암호화 설정을 Spring Security에 통합 + DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); + authProvider.setUserDetailsService(myUserDetailsService); // 사용자 세부 정보를 제공하는 서비스 설정 + authProvider.setPasswordEncoder(passwordEncoder); // 비밀번호 암호화 설정 + return authProvider; + } } diff --git a/src/main/java/com/example/healthylife/config/SwaggerConfig.java b/src/main/java/com/example/healthylife/config/SwaggerConfig.java index 0eb62b0..5c6a0d1 100644 --- a/src/main/java/com/example/healthylife/config/SwaggerConfig.java +++ b/src/main/java/com/example/healthylife/config/SwaggerConfig.java @@ -20,37 +20,19 @@ @Configuration @EnableSwagger2 public class SwaggerConfig { + @Bean public Docket api() { return new Docket(DocumentationType.OAS_30) -// .consumes(getConsumeContentTypes()) -// .produces(getProduceContentTypes()) - .apiInfo(getApiInfo()) + .useDefaultResponseMessages(false) .select() .apis(RequestHandlerSelectors.basePackage("com.example.healthylife")) - .paths(PathSelectors.ant("/**")) + .paths(PathSelectors.any()) .build() - .pathMapping("/") -// .host("localhost:8081") - .securityContexts(List.of(securityContext())) - .securitySchemes(List.of(apiKey())); - + .apiInfo(getApiInfo()); } -// private Set getConsumeContentTypes() { -// Set consumes = new HashSet<>(); -// consumes.add("application/json;charset=UTF-8"); -// consumes.add("application/x-www-form-urlencoded"); -// return consumes; -// } -// -// private Set getProduceContentTypes() { -// Set produces = new HashSet<>(); -// produces.add("application/json;charset=UTF-8"); -// return produces; -// } - private ApiInfo getApiInfo() { return new ApiInfoBuilder() .title("API") @@ -59,20 +41,6 @@ private ApiInfo getApiInfo() { .version("1.0") .build(); } - private SecurityScheme apiKey() { - return new ApiKey("Authorization", "Authorization", "header"); - } - private SecurityContext securityContext() { - return SecurityContext.builder() - .securityReferences(defaultAuth()) - .build(); - } - private List defaultAuth() { - AuthorizationScope authorizationScope = new AuthorizationScope("global", "accessEverything"); - AuthorizationScope[] authorizationScopes = new AuthorizationScope[1]; - authorizationScopes[0] = authorizationScope; - return List.of(new SecurityReference("Authorization", authorizationScopes)); - } } \ No newline at end of file diff --git a/src/main/java/com/example/healthylife/controller/CommunityController.java b/src/main/java/com/example/healthylife/controller/CommunityController.java index b52882e..e6f140c 100644 --- a/src/main/java/com/example/healthylife/controller/CommunityController.java +++ b/src/main/java/com/example/healthylife/controller/CommunityController.java @@ -23,16 +23,10 @@ public class CommunityController { @ApiOperation(value = "커뮤니티 글 전체 조회") @GetMapping("/all") public List communityList() { - // validate - // (http)param binding - // service call List communityEntities = communityService.communityList(); - // return result return communityEntities; } - - //커뮤니티 단일조회 (userId가지고 내가 쓴 글 조회) @ApiOperation(value = "커뮤니티 내가 쓴 글 조회") @GetMapping("/myCommunityContents") public ResponseEntity> myCommunityContentsList(@RequestHeader("Authorization") String authorizationHeader) { @@ -56,20 +50,19 @@ public CommunityEntity register(@RequestBody CommunityEntity communityEntity) { } @ApiOperation(value = "커뮤니티 글 수정") - @PostMapping("/update") + @PutMapping("/update") public CommunityEntity update(@RequestBody CommunityEntity communityEntity) { return communityService.updateCommunity(communityEntity); } - @ApiOperation(value = "커뮤니티 글 삭제") - @PostMapping("/delete") - public Boolean delete(@RequestParam long communitySq) { + @DeleteMapping("/delete/{communitySq}") + public ResponseEntity delete(@PathVariable("communitySq") Long communitySq) { communityService.deleteBySq(communitySq); - return true; + return ResponseEntity.noContent().build(); } - @ApiOperation(value = "커뮤니티 단일조회") + @ApiOperation(value = "커뮤니티 상세보기") @GetMapping("/communityDetail/{communitySq}") public ResponseEntity getCommunityBySq(@PathVariable("communitySq") Long communitySq) { try { @@ -80,13 +73,18 @@ public ResponseEntity getCommunityBySq(@PathVariable("community return new ResponseEntity<>(HttpStatus.NOT_FOUND); } } catch (Exception e) { - // 로그를 남기거나 필요한 조치를 취합니다 return new ResponseEntity<>(HttpStatus.INTERNAL_SERVER_ERROR); } } - // 커뮤니티 글 조회수 - @ApiOperation(value = "커뮤니티 글 추천") + @ApiOperation(value = "커뮤니티 글 추천수") + @PostMapping("/recommend/{sq}") + public ResponseEntity communityRecommend(@PathVariable("sq") Long sq) { + long updatedCount = communityService.toggleRecommendation(sq); + return ResponseEntity.ok(updatedCount); + } + + @ApiOperation(value = "커뮤니티 글 조회수") @PostMapping("/view/{sq}") public ResponseEntity Communityview(@PathVariable("sq") Long sq) { communityService.incrementview(sq); diff --git a/src/main/java/com/example/healthylife/controller/JwtLoginAuthController.java b/src/main/java/com/example/healthylife/controller/JwtLoginAuthController.java index 59303e1..c6ea372 100644 --- a/src/main/java/com/example/healthylife/controller/JwtLoginAuthController.java +++ b/src/main/java/com/example/healthylife/controller/JwtLoginAuthController.java @@ -8,7 +8,6 @@ import io.swagger.annotations.ApiOperation; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.authentication.AuthenticationManager; @@ -61,38 +60,30 @@ public ResponseEntity authenticate(@RequestBody LoginRequest loginReques } } - @GetMapping("/refresh") - public ResponseEntity refresh(@RequestParam("refresh-token") String refreshToken){ - try { - String accessToken = jwtAuthService.refresh(refreshToken); - //사용자 이름(아이디)과 비번으로 인증 - - - Map result = Map.of("access-token", accessToken, - "refresh-token", refreshToken); - - //생성된 토큰을 ResponseEntity로 반환 - return ResponseEntity.ok() - .body(objectMapper.writeValueAsString(result)); - } catch (Exception e) { - log.error("refresh failed! - refresh-token: {}", refreshToken, e); - return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) - .body("Exception : " + e.getMessage()); - } - - } +// 현재 사용안함 +// @GetMapping("/refresh") +// public ResponseEntity refresh(@RequestParam("refresh-token") String refreshToken){ +// try { +// String accessToken = jwtAuthService.refresh(refreshToken); +// //사용자 이름(아이디)과 비번으로 인증 +// +// +// Map result = Map.of("access-token", accessToken, +// "refresh-token", refreshToken); +// +// //생성된 토큰을 ResponseEntity로 반환 +// return ResponseEntity.ok() +// .body(objectMapper.writeValueAsString(result)); +// } catch (Exception e) { +// log.error("refresh failed! - refresh-token: {}", refreshToken, e); +// return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR) +// .body("Exception : " + e.getMessage()); +// } +// +// } - @ApiOperation("로그아웃 컨트롤러") - @GetMapping("/logout") - public ResponseEntity logout(@RequestParam("username") String username) { - // 클라이언트 측에서 토큰을 삭제하도록 처리 -// response.setHeader("Set-Cookie", "accessToken=; HttpOnly; Path=/; Max-Age=0"); -// response.setHeader("Set-Cookie", "refreshToken=; HttpOnly; Path=/; Max-Age=0"); - jwtAuthService.logout(username); - return ResponseEntity.ok().body("Logout Successful"); - } } \ No newline at end of file diff --git a/src/main/java/com/example/healthylife/entity/CommunityEntity.java b/src/main/java/com/example/healthylife/entity/CommunityEntity.java index ee35ebd..6974abf 100644 --- a/src/main/java/com/example/healthylife/entity/CommunityEntity.java +++ b/src/main/java/com/example/healthylife/entity/CommunityEntity.java @@ -27,7 +27,7 @@ public class CommunityEntity implements Serializable { private String communityTitle; //글내용 - @Column(name = "community_contents",length = 500) + @Column(name = "community_contents",length = 1000) private String communityContents; //커뮤니티 게시글 작성일 @@ -37,7 +37,7 @@ public class CommunityEntity implements Serializable { //커뮤니티 글 조회수 //communityview - @Column(name = "communityview", length = 200 ) + @Column(name = "community_view", length = 200 ) private int communityview; //커뮤니티 글 추천수 @@ -67,7 +67,14 @@ public CommunityEntity(long communitySq, String communityTitle, String community this.user = user; } - + // 추천수 + public void toggleRecommendation(boolean currentlyRecommended) { + if (currentlyRecommended) { + this.communityRecommend--; + } else { + this.communityRecommend++; + } + } } diff --git a/src/main/java/com/example/healthylife/service/CommunityService.java b/src/main/java/com/example/healthylife/service/CommunityService.java index ce2bc7b..e4cfed2 100644 --- a/src/main/java/com/example/healthylife/service/CommunityService.java +++ b/src/main/java/com/example/healthylife/service/CommunityService.java @@ -17,7 +17,6 @@ public class CommunityService { private final CommunityRepository communityRepository; - private final UserRepository userRepository; private final CommunityCommentsService communityCommentsService; @@ -26,26 +25,23 @@ public List communityList() { return communityRepository.findAll(); } - //커뮤니티 글 작성 public CommunityEntity registerCommunity(CommunityEntity communityEntity) { return communityRepository.save(communityEntity); } - //커뮤니티 글 수정 @Transactional public CommunityEntity updateCommunity(CommunityEntity communityEntity) { - return communityRepository.save(communityEntity); } //커뮤니티 글 삭제 public void deleteBySq(long communitySq) { - communityRepository.deleteById(communitySq); } + //커뮤니티 내가 쓴글 조회 public List findMyContents(String userId) { return communityRepository.findByUserUserId(userId); } @@ -60,6 +56,18 @@ public Optional findCommunityBySq(Long communitySq) { return community; } + //커뮤니티 추천수 + @Transactional + public long toggleRecommendation(Long sq) { + CommunityEntity community = communityRepository.findById(sq) + .orElseThrow(() -> new RuntimeException("커뮤니티가 없습니다.")); + + boolean isRecommended = community.getCommunityRecommend() > 0; + community.toggleRecommendation(isRecommended); + CommunityEntity updatedCommunity = communityRepository.save(community); + return updatedCommunity.getCommunityRecommend(); + } + // 커뮤니티 조회수 @Transactional public void incrementview(Long communitySq) { @@ -69,15 +77,3 @@ public void incrementview(Long communitySq) { } - - //커뮤니티 내가 쓴 글 조회 -// @Override -// public List findMyContents(long userSq) { -// return communityRepository.findByUserUserId(userSq); -// } - - - - - - diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 1d0209c..f75a1ef 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,6 +1,5 @@ server: port: 8081 -# connection-timeout: 190s # 전체 연결 타임아웃 tomcat: connection-timeout: 66000ms # 연결 타임아웃 keep-alive-timeout: 65000ms # Keep-Alive 타임아웃 @@ -8,34 +7,26 @@ server: jwt: secret: "sklskljsklsjalkjklsjSKLSAKLJsklsklsjlksjsakljslkajsalksaksa" - accessTokenExpTime: 600000 # 10 minutes in milliseconds - refreshTokenExpTime: 86400000 # 24 hours in milliseconds - - #JDBC datasource -#spring: -# datasource: -# hikari: -# driver-class-name: oracle.jdbc.OracleDriver -# jdbc-url: jdbc:oracle:thin:@localhost:1521:XE -# username: kimjisoo -# password: pass - -#JDBC spy datasource -log4jdbc: - spylogdelegator: - name: net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator + accessTokenExpTime: 600000 # 10 minutes in milliseconds + refreshTokenExpTime: 86400000 # 24 hours in milliseconds spring: + http: + encoding: + charset: UTF-8 + enabled: true + force: true + mvc: pathmatch: matching-strategy: ant_path_matcher + datasource: driver-class-name: org.mariadb.jdbc.Driver - url: jdbc:mariadb://database-2.ch0kog84exlz.ap-northeast-2.rds.amazonaws.com:3306/Trendy_Devs + url: jdbc:mariadb://database-2.ch0kog84exlz.ap-northeast-2.rds.amazonaws.com:3306/Trendy_Devs?useUnicode=true&characterEncoding=utf8mb4 username: Trendy_Devs password: koreait123 - # jpa jpa: hibernate: ddl-auto: update @@ -44,10 +35,13 @@ spring: format_sql: true show_sql: true use_sql_comments: true + profiles: include: private -# S3 +log4jdbc: + spylogdelegator: + name: net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator management: endpoints: @@ -57,11 +51,3 @@ management: endpoint: health: show-details: always # 상세 정보를 항상 표시합니다. - - - -# hikari: -# driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy -# jdbc-url: jdbc:log4jdbc:oracle:thin:@localhost:1521:XE -# username: kimjisoo -# password: pass