diff --git a/.gitignore b/.gitignore index c2065bc..2f8aee8 100644 Binary files a/.gitignore and b/.gitignore differ diff --git a/build.gradle b/build.gradle index d6dd785..dbf9922 100644 --- a/build.gradle +++ b/build.gradle @@ -25,11 +25,22 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.mysql:mysql-connector-j' + + // swagger + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0' + + + implementation 'io.jsonwebtoken:jjwt-api:0.12.3' + implementation 'io.jsonwebtoken:jjwt-impl:0.12.3' + implementation 'io.jsonwebtoken:jjwt-jackson:0.12.3' + annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' + testImplementation 'org.springframework.security:spring-security-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' } diff --git a/src/main/java/com/example/springhw4/config/CorsMvcConfig.java b/src/main/java/com/example/springhw4/config/CorsMvcConfig.java new file mode 100644 index 0000000..30c0d32 --- /dev/null +++ b/src/main/java/com/example/springhw4/config/CorsMvcConfig.java @@ -0,0 +1,16 @@ +package com.example.springhw4.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; + +@Configuration +public class CorsMvcConfig implements WebMvcConfigurer { + + @Override + public void addCorsMappings(CorsRegistry corsRegistry) { + + corsRegistry.addMapping("/**") + .allowedOrigins("http://localhost:3000"); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/springhw4/config/SecurityConfig.java b/src/main/java/com/example/springhw4/config/SecurityConfig.java new file mode 100644 index 0000000..660c462 --- /dev/null +++ b/src/main/java/com/example/springhw4/config/SecurityConfig.java @@ -0,0 +1,99 @@ +package com.example.springhw4.config; + +import com.example.springhw4.jwt.JWTFilter; +import com.example.springhw4.jwt.JWTUtil; +import com.example.springhw4.jwt.LoginFilter; +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.config.annotation.authentication.configuration.AuthenticationConfiguration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.http.SessionCreationPolicy; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; +import org.springframework.web.cors.CorsConfiguration; +import org.springframework.web.cors.CorsConfigurationSource; + +import java.util.Collections; + + +@Configuration +@EnableWebSecurity +public class SecurityConfig { + + private final AuthenticationConfiguration authenticationConfiguration; + //JWTUtil 주입 + private final JWTUtil jwtUtil; + + public SecurityConfig(AuthenticationConfiguration authenticationConfiguration, JWTUtil jwtUtil) { + + this.authenticationConfiguration = authenticationConfiguration; + this.jwtUtil = jwtUtil; + } + + @Bean + public AuthenticationManager authenticationManager(AuthenticationConfiguration configuration) throws Exception { + + return configuration.getAuthenticationManager(); + } + + @Bean + public BCryptPasswordEncoder bCryptPasswordEncoder() { + + return new BCryptPasswordEncoder(); + } + + @Bean + public SecurityFilterChain filterChain(HttpSecurity http) throws Exception { + + http + .cors((corsCustomizer -> corsCustomizer.configurationSource(new CorsConfigurationSource() { + + @Override + public CorsConfiguration getCorsConfiguration(HttpServletRequest request) { + + CorsConfiguration configuration = new CorsConfiguration(); + + configuration.setAllowedOrigins(Collections.singletonList("http://localhost:3000")); + configuration.setAllowedMethods(Collections.singletonList("*")); + configuration.setAllowCredentials(true); + configuration.setAllowedHeaders(Collections.singletonList("*")); + configuration.setMaxAge(3600L); + + configuration.setExposedHeaders(Collections.singletonList("Authorization")); + + return configuration; + } + }))); + + http + .csrf((auth) -> auth.disable()); + + http + .formLogin((auth) -> auth.disable()); + + http + .httpBasic((auth) -> auth.disable()); + + http + .authorizeHttpRequests((auth) -> auth + .requestMatchers("/login", "/", "/join","/docs/**","/v3/**").permitAll() + .anyRequest().authenticated()); + + //JWTFilter 등록 + http + .addFilterBefore(new JWTFilter(jwtUtil), LoginFilter.class); + + http + .addFilterAt(new LoginFilter(authenticationManager(authenticationConfiguration), jwtUtil), UsernamePasswordAuthenticationFilter.class); + + http + .sessionManagement((session) -> session + .sessionCreationPolicy(SessionCreationPolicy.STATELESS)); + + return http.build(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/springhw4/config/SwaggerConfig.java b/src/main/java/com/example/springhw4/config/SwaggerConfig.java new file mode 100644 index 0000000..3d6b0b1 --- /dev/null +++ b/src/main/java/com/example/springhw4/config/SwaggerConfig.java @@ -0,0 +1,38 @@ +package com.example.springhw4.config; + +import io.swagger.v3.oas.models.Components; +import io.swagger.v3.oas.models.OpenAPI; +import io.swagger.v3.oas.models.security.SecurityRequirement; +import io.swagger.v3.oas.models.security.SecurityScheme; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + + +import java.util.List; + +@Configuration +public class SwaggerConfig { + + @Bean + public OpenAPI openAPI() { + SecurityScheme apiKey = new SecurityScheme() + .type(SecurityScheme.Type.HTTP) + .in(SecurityScheme.In.HEADER) + .name("Authorization") + .scheme("bearer") + .bearerFormat("JWT"); + + SecurityRequirement securityRequirement = new SecurityRequirement() + .addList("Bearer Token"); + + return new OpenAPI() + .components(new Components().addSecuritySchemes("Bearer Token", apiKey)) + .addSecurityItem(securityRequirement) + .servers(List.of( + new io.swagger.v3.oas.models.servers.Server() + .url("http://localhost:8080") + .description("로컬 서버") + ) + ); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/springhw4/controller/AdminController.java b/src/main/java/com/example/springhw4/controller/AdminController.java new file mode 100644 index 0000000..0544810 --- /dev/null +++ b/src/main/java/com/example/springhw4/controller/AdminController.java @@ -0,0 +1,17 @@ +package com.example.springhw4.controller; + +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@ResponseBody +public class AdminController { + + @GetMapping("/admin") + public String adminP(){ + + return "admin Controller"; + } + +} diff --git a/src/main/java/com/example/springhw4/controller/JoinController.java b/src/main/java/com/example/springhw4/controller/JoinController.java new file mode 100644 index 0000000..e52afa7 --- /dev/null +++ b/src/main/java/com/example/springhw4/controller/JoinController.java @@ -0,0 +1,28 @@ +package com.example.springhw4.controller; + +import com.example.springhw4.dto.JoinDTO; +import com.example.springhw4.service.JoinService; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +@Controller +@ResponseBody +public class JoinController { + + private final JoinService joinService; + + public JoinController(JoinService joinService) { + + this.joinService = joinService; + } + + @PostMapping("/join") + public String joinProcess(JoinDTO joinDTO) { + + System.out.println(joinDTO.getUsername()); + joinService.joinProcess(joinDTO); + + return "ok"; + } +} \ No newline at end of file diff --git a/src/main/java/com/example/springhw4/controller/MainController.java b/src/main/java/com/example/springhw4/controller/MainController.java new file mode 100644 index 0000000..bf7101f --- /dev/null +++ b/src/main/java/com/example/springhw4/controller/MainController.java @@ -0,0 +1,31 @@ +package com.example.springhw4.controller; + +import org.springframework.security.core.Authentication; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.ResponseBody; + +import java.util.Collection; +import java.util.Iterator; + +@Controller +@ResponseBody +public class MainController { + + @GetMapping("/") + public String mainP() { + + String name = SecurityContextHolder.getContext().getAuthentication().getName(); + + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + + Collection authorities = authentication.getAuthorities(); + Iterator iter = authorities.iterator(); + GrantedAuthority auth = iter.next(); + String role = auth.getAuthority(); + + return "Main Controller : "+name+role; + } +} diff --git a/src/main/java/com/example/springhw4/controller/PostController.java b/src/main/java/com/example/springhw4/controller/PostController.java new file mode 100644 index 0000000..f1cd77e --- /dev/null +++ b/src/main/java/com/example/springhw4/controller/PostController.java @@ -0,0 +1,17 @@ +package com.example.springhw4.controller; + +import com.example.springhw4.dto.PostDto; +import lombok.Getter; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class PostController { + + @GetMapping("/post") + public String createpost() { + return SecurityContextHolder.getContext().getAuthentication().getName(); + } + +} diff --git a/src/main/java/com/example/springhw4/dto/CustomUserDetails.java b/src/main/java/com/example/springhw4/dto/CustomUserDetails.java new file mode 100644 index 0000000..7e8c55d --- /dev/null +++ b/src/main/java/com/example/springhw4/dto/CustomUserDetails.java @@ -0,0 +1,73 @@ +package com.example.springhw4.dto; + +import com.example.springhw4.entity.UserEntity; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.core.userdetails.UserDetails; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +public class CustomUserDetails implements UserDetails { + + private final UserEntity userEntity; + + public CustomUserDetails(UserEntity userEntity) { + + this.userEntity = userEntity; + } + + + @Override + public Collection getAuthorities() { + + Collection collection = new ArrayList<>(); + + collection.add(new GrantedAuthority() { + + @Override + public String getAuthority() { + + return userEntity.getRole(); + } + }); + + return collection; + } + + @Override + public String getPassword() { + + return userEntity.getPassword(); + } + + @Override + public String getUsername() { + + return userEntity.getUsername(); + } + + @Override + public boolean isAccountNonExpired() { + + return true; + } + + @Override + public boolean isAccountNonLocked() { + + return true; + } + + @Override + public boolean isCredentialsNonExpired() { + + return true; + } + + @Override + public boolean isEnabled() { + + return true; + } +} diff --git a/src/main/java/com/example/springhw4/dto/JoinDTO.java b/src/main/java/com/example/springhw4/dto/JoinDTO.java new file mode 100644 index 0000000..858e400 --- /dev/null +++ b/src/main/java/com/example/springhw4/dto/JoinDTO.java @@ -0,0 +1,12 @@ +package com.example.springhw4.dto; + +import lombok.Getter; +import lombok.Setter; + +@Setter +@Getter +public class JoinDTO { + + private String username; + private String password; +} \ No newline at end of file diff --git a/src/main/java/com/example/springhw4/dto/PostDto.java b/src/main/java/com/example/springhw4/dto/PostDto.java new file mode 100644 index 0000000..25f484f --- /dev/null +++ b/src/main/java/com/example/springhw4/dto/PostDto.java @@ -0,0 +1,16 @@ +package com.example.springhw4.dto; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Builder +@Getter +@Setter +public class PostDto { + + private String title; + + private String content; + +} diff --git a/src/main/java/com/example/springhw4/entity/Post.java b/src/main/java/com/example/springhw4/entity/Post.java new file mode 100644 index 0000000..3201d0f --- /dev/null +++ b/src/main/java/com/example/springhw4/entity/Post.java @@ -0,0 +1,23 @@ +package com.example.springhw4.entity; + +import jakarta.persistence.*; +import lombok.*; + +@Entity +@Builder +@Getter +@NoArgsConstructor +@AllArgsConstructor +public class Post { + + @Id + @GeneratedValue(strategy = GenerationType.AUTO) + private Long id; + + @ManyToOne + private UserEntity userEntity; + + private String title; + private String content; + +} diff --git a/src/main/java/com/example/springhw4/entity/UserEntity.java b/src/main/java/com/example/springhw4/entity/UserEntity.java new file mode 100644 index 0000000..34fab55 --- /dev/null +++ b/src/main/java/com/example/springhw4/entity/UserEntity.java @@ -0,0 +1,24 @@ +package com.example.springhw4.entity; + +import jakarta.persistence.Entity; +import jakarta.persistence.GeneratedValue; +import jakarta.persistence.GenerationType; +import jakarta.persistence.Id; +import lombok.Getter; +import lombok.Setter; + +@Entity +@Getter +@Setter +public class UserEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + private int id; + + private String username; + + private String password; + + private String role; +} diff --git a/src/main/java/com/example/springhw4/jwt/JWTFilter.java b/src/main/java/com/example/springhw4/jwt/JWTFilter.java new file mode 100644 index 0000000..010eea6 --- /dev/null +++ b/src/main/java/com/example/springhw4/jwt/JWTFilter.java @@ -0,0 +1,74 @@ +package com.example.springhw4.jwt; + +import com.example.springhw4.dto.CustomUserDetails; +import com.example.springhw4.entity.UserEntity; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +public class JWTFilter extends OncePerRequestFilter { + + private final JWTUtil jwtUtil; + + public JWTFilter(JWTUtil jwtUtil) { + + this.jwtUtil = jwtUtil; + } + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + //request에서 Authorization 헤더를 찾음 + String authorization= request.getHeader("Authorization"); + + //Authorization 헤더 검증 + if (authorization == null || !authorization.startsWith("Bearer ")) { + + System.out.println("token null"); + filterChain.doFilter(request, response); + + //조건이 해당되면 메소드 종료 (필수) + return; + } + + System.out.println("authorization now"); + //Bearer 부분 제거 후 순수 토큰만 획득 + String token = authorization.split(" ")[1]; + + //토큰 소멸 시간 검증 + if (jwtUtil.isExpired(token)) { + + System.out.println("token expired"); + filterChain.doFilter(request, response); + + //조건이 해당되면 메소드 종료 (필수) + return; + } + + //토큰에서 username과 role 획득 + String username = jwtUtil.getUsername(token); + String role = jwtUtil.getRole(token); + + //userEntity를 생성하여 값 set + UserEntity userEntity = new UserEntity(); + userEntity.setUsername(username); + userEntity.setPassword("temppassword"); + userEntity.setRole(role); + + //UserDetails에 회원 정보 객체 담기 + CustomUserDetails customUserDetails = new CustomUserDetails(userEntity); + + //스프링 시큐리티 인증 토큰 생성 + Authentication authToken = new UsernamePasswordAuthenticationToken(customUserDetails, null, customUserDetails.getAuthorities()); + //세션에 사용자 등록 + SecurityContextHolder.getContext().setAuthentication(authToken); + + filterChain.doFilter(request, response); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/springhw4/jwt/JWTUtil.java b/src/main/java/com/example/springhw4/jwt/JWTUtil.java new file mode 100644 index 0000000..c48ae3e --- /dev/null +++ b/src/main/java/com/example/springhw4/jwt/JWTUtil.java @@ -0,0 +1,48 @@ +package com.example.springhw4.jwt; + +import io.jsonwebtoken.Jwts; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import javax.crypto.SecretKey; +import javax.crypto.spec.SecretKeySpec; +import java.nio.charset.StandardCharsets; +import java.util.Date; + +@Component +public class JWTUtil { + + private SecretKey secretKey; + + public JWTUtil(@Value("${spring.jwt.secret}")String secret) { + + + secretKey = new SecretKeySpec(secret.getBytes(StandardCharsets.UTF_8), Jwts.SIG.HS256.key().build().getAlgorithm()); + } + + public String getUsername(String token) { + + return Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token).getPayload().get("username", String.class); + } + + public String getRole(String token) { + + return Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token).getPayload().get("role", String.class); + } + + public Boolean isExpired(String token) { + + return Jwts.parser().verifyWith(secretKey).build().parseSignedClaims(token).getPayload().getExpiration().before(new Date()); + } + + public String createJwt(String username, String role, Long expiredMs) { + + return Jwts.builder() + .claim("username", username) + .claim("role", role) + .issuedAt(new Date(System.currentTimeMillis())) + .expiration(new Date(System.currentTimeMillis() + expiredMs)) + .signWith(secretKey) + .compact(); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/springhw4/jwt/LoginFilter.java b/src/main/java/com/example/springhw4/jwt/LoginFilter.java new file mode 100644 index 0000000..c7d3aa6 --- /dev/null +++ b/src/main/java/com/example/springhw4/jwt/LoginFilter.java @@ -0,0 +1,72 @@ +package com.example.springhw4.jwt; + +import com.example.springhw4.dto.CustomUserDetails; +import jakarta.servlet.FilterChain; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import jdk.swing.interop.SwingInterOpUtils; +import org.springframework.security.authentication.AuthenticationManager; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.AuthenticationException; +import org.springframework.security.core.GrantedAuthority; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +import java.util.Collection; +import java.util.Iterator; + +public class LoginFilter extends UsernamePasswordAuthenticationFilter { + + private final AuthenticationManager authenticationManager; + //JWTUtil 주입 + private final JWTUtil jwtUtil; + + public LoginFilter(AuthenticationManager authenticationManager, JWTUtil jwtUtil) { + + this.authenticationManager = authenticationManager; + this.jwtUtil = jwtUtil; + } + + @Override + public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException { + + //클라이언트 요청에서 username, password 추출 + String username = obtainUsername(request); + String password = obtainPassword(request); + + //스프링 시큐리티에서 username과 password를 검증하기 위해서는 token에 담아야 함 + UsernamePasswordAuthenticationToken authToken = new UsernamePasswordAuthenticationToken(username, password, null); + + //token에 담은 검증을 위한 AuthenticationManager로 전달 + return authenticationManager.authenticate(authToken); + } + + //로그인 성공시 실행하는 메소드 (여기서 JWT를 발급하면 됨) + @Override + protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, Authentication authentication) { + + //UserDetailsS + CustomUserDetails customUserDetails = (CustomUserDetails) authentication.getPrincipal(); + + String username = customUserDetails.getUsername(); + + Collection authorities = authentication.getAuthorities(); + Iterator iterator = authorities.iterator(); + GrantedAuthority auth = iterator.next(); + + String role = auth.getAuthority(); + + //10시간 설정 + String token = jwtUtil.createJwt(username, role, 60*60*1000L); + + response.addHeader("Authorization", "Bearer " + token); + } + + //로그인 실패시 실행하는 메소드 + @Override + protected void unsuccessfulAuthentication(HttpServletRequest request, HttpServletResponse response, AuthenticationException failed) { + + //로그인 실패시 401 응답 코드 반환 + response.setStatus(401); + } +} \ No newline at end of file diff --git a/src/main/java/com/example/springhw4/repository/PostRepository.java b/src/main/java/com/example/springhw4/repository/PostRepository.java new file mode 100644 index 0000000..4410481 --- /dev/null +++ b/src/main/java/com/example/springhw4/repository/PostRepository.java @@ -0,0 +1,11 @@ +package com.example.springhw4.repository; + +import com.example.springhw4.entity.Post; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; +import org.springframework.web.bind.annotation.ResponseBody; + +@Repository +public interface PostRepository extends JpaRepository { + +} diff --git a/src/main/java/com/example/springhw4/repository/UserRepository.java b/src/main/java/com/example/springhw4/repository/UserRepository.java new file mode 100644 index 0000000..0e07007 --- /dev/null +++ b/src/main/java/com/example/springhw4/repository/UserRepository.java @@ -0,0 +1,12 @@ +package com.example.springhw4.repository; + +import com.example.springhw4.entity.UserEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserRepository extends JpaRepository { + + Boolean existsByUsername(String username); + + //username을 받아 DB 테이블에서 회원을 조회하는 메소드 작성 + UserEntity findByUsername(String username); +} \ No newline at end of file diff --git a/src/main/java/com/example/springhw4/service/CustomUserDetailsService.java b/src/main/java/com/example/springhw4/service/CustomUserDetailsService.java new file mode 100644 index 0000000..f4d1492 --- /dev/null +++ b/src/main/java/com/example/springhw4/service/CustomUserDetailsService.java @@ -0,0 +1,35 @@ +package com.example.springhw4.service; + +import com.example.springhw4.dto.CustomUserDetails; +import com.example.springhw4.entity.UserEntity; +import com.example.springhw4.repository.UserRepository; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.security.core.userdetails.UserDetailsService; +import org.springframework.security.core.userdetails.UsernameNotFoundException; +import org.springframework.stereotype.Service; + +@Service +public class CustomUserDetailsService implements UserDetailsService { + + private final UserRepository userRepository; + + public CustomUserDetailsService(UserRepository userRepository) { + + this.userRepository = userRepository; + } + + @Override + public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException { + + //DB에서 조회 + UserEntity userData = userRepository.findByUsername(username); + + if (userData != null) { + + //UserDetails에 담아서 return하면 AutneticationManager가 검증 함 + return new CustomUserDetails(userData); + } + + return null; + } +} diff --git a/src/main/java/com/example/springhw4/service/JoinService.java b/src/main/java/com/example/springhw4/service/JoinService.java new file mode 100644 index 0000000..3a53bb0 --- /dev/null +++ b/src/main/java/com/example/springhw4/service/JoinService.java @@ -0,0 +1,41 @@ +package com.example.springhw4.service; + +import com.example.springhw4.dto.JoinDTO; +import com.example.springhw4.entity.UserEntity; +import com.example.springhw4.repository.UserRepository; +import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.stereotype.Service; + +@Service +public class JoinService { + + private final UserRepository userRepository; + private final BCryptPasswordEncoder bCryptPasswordEncoder; + + public JoinService(UserRepository userRepository, BCryptPasswordEncoder bCryptPasswordEncoder) { + + this.userRepository = userRepository; + this.bCryptPasswordEncoder = bCryptPasswordEncoder; + } + + public void joinProcess(JoinDTO joinDTO) { + + String username = joinDTO.getUsername(); + String password = joinDTO.getPassword(); + + Boolean isExist = userRepository.existsByUsername(username); + + if (isExist) { + + return; + } + + UserEntity data = new UserEntity(); + + data.setUsername(username); + data.setPassword(bCryptPasswordEncoder.encode(password)); + data.setRole("ROLE_ADMIN"); + + userRepository.save(data); + } +} diff --git a/src/main/java/com/example/springhw4/service/PostService.java b/src/main/java/com/example/springhw4/service/PostService.java new file mode 100644 index 0000000..206d2e0 --- /dev/null +++ b/src/main/java/com/example/springhw4/service/PostService.java @@ -0,0 +1,8 @@ +package com.example.springhw4.service; + +import org.springframework.stereotype.Service; + +@Service +public class PostService { + +} diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 9b78d0c..6b904d4 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,15 +1,26 @@ spring: datasource: - url: jdbc:mysql://localhost:3306/your_database_name?useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8 + url: jdbc:mysql://localhost:3306/demo?useSSL=false&serverTimezone=UTC&characterEncoding=UTF-8 username: your_username password: your_password driver-class-name: com.mysql.cj.jdbc.Driver jpa: hibernate: - ddl-auto: create + ddl-auto: update show-sql: true properties: hibernate: format_sql: true - dialect: org.hibernate.dialect.MySQL8Dialect \ No newline at end of file + dialect: org.hibernate.dialect.MySQL8Dialect + + jwt: + secret: vmfhaltmskdlstkfkdgodyroqkfwkdbalroqkfwkdbalaaaaaaaaaaaaaaaabbbbb + +springdoc: + api-docs: + enabled: true + path: /v3/api-docs + swagger-ui: + enabled: true + path: /docs/index.html