From d36ad32108a11812b08ac68f83d8636c8caf492f Mon Sep 17 00:00:00 2001 From: ksg Date: Mon, 18 Nov 2024 16:49:45 +0900 Subject: [PATCH 1/6] =?UTF-8?q?feat:=20UserController=20=EC=99=84=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../com/kuit/kuit4serverauth/config/WebConfig.java | 3 +++ .../kuit4serverauth/controller/UserController.java | 11 +++++++++++ .../com/kuit/kuit4serverauth/service/JwtUtil.java | 8 ++++++-- src/main/resources/application.yml | 2 +- 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/main/java/com/kuit/kuit4serverauth/config/WebConfig.java b/src/main/java/com/kuit/kuit4serverauth/config/WebConfig.java index a0b47b4..86b86ce 100644 --- a/src/main/java/com/kuit/kuit4serverauth/config/WebConfig.java +++ b/src/main/java/com/kuit/kuit4serverauth/config/WebConfig.java @@ -16,5 +16,8 @@ public WebConfig(AuthInterceptor authInterceptor) { @Override public void addInterceptors(InterceptorRegistry registry) { // TODO /profile, /admin 앞에 붙이기 + registry.addInterceptor(authInterceptor) + .addPathPatterns("/profile") + .addPathPatterns("/admin"); } } diff --git a/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java b/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java index 18cb7af..fdf68e7 100644 --- a/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java +++ b/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java @@ -1,5 +1,6 @@ package com.kuit.kuit4serverauth.controller; +import com.kuit.kuit4serverauth.repository.UserRepository; import jakarta.servlet.http.HttpServletRequest; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -12,12 +13,22 @@ public class UserController { @GetMapping("/profile") public ResponseEntity getProfile(HttpServletRequest request) { // TODO : 로그인 한 사용자면 username 이용해 "Hello, {username}" 반환하기 + String username = (String) request.getAttribute("username"); + + if (username != null) { + return ResponseEntity.ok("Hello, " + username); + } + return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized"); } @GetMapping("/admin") public ResponseEntity getAdmin(HttpServletRequest request) { // TODO: role이 admin이면 "Hello, admin" 반환하기 + String role = (String) request.getAttribute("role"); + if (role != null && role.equals("ROLE_ADMIN")) { + return ResponseEntity.ok("Hello, admin"); + } return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Forbidden"); } } diff --git a/src/main/java/com/kuit/kuit4serverauth/service/JwtUtil.java b/src/main/java/com/kuit/kuit4serverauth/service/JwtUtil.java index ead240e..928516b 100644 --- a/src/main/java/com/kuit/kuit4serverauth/service/JwtUtil.java +++ b/src/main/java/com/kuit/kuit4serverauth/service/JwtUtil.java @@ -5,14 +5,18 @@ import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; import io.jsonwebtoken.SignatureAlgorithm; +import org.springframework.beans.factory.annotation.Value; import org.springframework.stereotype.Component; import java.util.Date; @Component public class JwtUtil { - private final String secret = "mysecretkey"; - private final long expirationMs = 3600000; // 1 hour + @Value("${jwt.secret}") + private String secret; + + @Value("${jwt.expiration}") + private long expirationMs; // 1 hour public String generateToken(String username, String role) { return Jwts.builder() diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 59bd888..01c5197 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -13,6 +13,6 @@ spring: path: /h2-console jwt: - secret: mysecretkey + secret: mysecretkey01234567890123456789012345678901234 expiration: 3600000 From 1b399d96dd8ede49034eb9301e2662c9472f0ccc Mon Sep 17 00:00:00 2001 From: ksg Date: Mon, 18 Nov 2024 19:03:44 +0900 Subject: [PATCH 2/6] =?UTF-8?q?feat:=20refreshToken=20=EA=B5=AC=ED=98=84?= =?UTF-8?q?=20=EB=B0=8F=20DTO=20=EB=8F=84=EC=9E=85?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../controller/AuthController.java | 33 +++++++++++++++---- .../controller/UserController.java | 2 -- .../kuit4serverauth/dto/LoginRequest.java | 12 +++++++ .../kuit4serverauth/dto/LoginResponse.java | 17 ++++++++++ .../kuit4serverauth/dto/TokenResponse.java | 15 +++++++++ .../kuit/kuit4serverauth/service/JwtUtil.java | 12 +++++++ src/main/resources/application.yml | 4 ++- 7 files changed, 86 insertions(+), 9 deletions(-) create mode 100644 src/main/java/com/kuit/kuit4serverauth/dto/LoginRequest.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/dto/LoginResponse.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/dto/TokenResponse.java diff --git a/src/main/java/com/kuit/kuit4serverauth/controller/AuthController.java b/src/main/java/com/kuit/kuit4serverauth/controller/AuthController.java index e8f7e24..a5f03a2 100644 --- a/src/main/java/com/kuit/kuit4serverauth/controller/AuthController.java +++ b/src/main/java/com/kuit/kuit4serverauth/controller/AuthController.java @@ -1,14 +1,19 @@ package com.kuit.kuit4serverauth.controller; +import com.kuit.kuit4serverauth.dto.LoginRequest; +import com.kuit.kuit4serverauth.dto.LoginResponse; +import com.kuit.kuit4serverauth.dto.TokenResponse; import com.kuit.kuit4serverauth.exception.CustomException; import com.kuit.kuit4serverauth.exception.ErrorCode; import com.kuit.kuit4serverauth.model.User; import com.kuit.kuit4serverauth.repository.UserRepository; import com.kuit.kuit4serverauth.service.JwtUtil; +import io.jsonwebtoken.Claims; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; import java.util.HashMap; @@ -25,18 +30,34 @@ public AuthController(UserRepository userRepository, JwtUtil jwtUtil) { } @PostMapping("/login") - public ResponseEntity> login(@RequestBody Map credentials) { - String username = credentials.get("username"); - String password = credentials.get("password"); + public ResponseEntity login(@RequestBody LoginRequest loginRequest) { + String username = loginRequest.getUsername(); + String password = loginRequest.getPassword(); User user = userRepository.findByUsername(username); if (user == null || !user.getPassword().equals(password)) { throw new CustomException(ErrorCode.INVALID_USERNAME_OR_PASSWORD); } - String token = jwtUtil.generateToken(user.getUsername(), user.getRole()); - Map response = new HashMap<>(); - response.put("token", token); + String accessToken = jwtUtil.generateToken(user.getUsername(), user.getRole()); + String refreshToken = jwtUtil.generateRefreshToken(user.getUsername()); + + LoginResponse response = new LoginResponse(accessToken, refreshToken); + return ResponseEntity.ok(response); + } + + // 해당 url로 요청을 보내면 RefreshToken을 통해 AccessToken을 새로 발급해줌. + @PostMapping("/refresh-token") + public ResponseEntity refreshToken(@RequestBody Map tokens) { + String refreshToken = tokens.get("refreshToken"); + + Claims claims = jwtUtil.validateToken(refreshToken); + String username = claims.getSubject(); + + String newAccessToken = jwtUtil.generateToken(username, (String)claims.get("role")); + + TokenResponse response = new TokenResponse(newAccessToken); + return ResponseEntity.ok(response); } } diff --git a/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java b/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java index fdf68e7..d58285a 100644 --- a/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java +++ b/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java @@ -12,7 +12,6 @@ public class UserController { @GetMapping("/profile") public ResponseEntity getProfile(HttpServletRequest request) { - // TODO : 로그인 한 사용자면 username 이용해 "Hello, {username}" 반환하기 String username = (String) request.getAttribute("username"); if (username != null) { @@ -24,7 +23,6 @@ public ResponseEntity getProfile(HttpServletRequest request) { @GetMapping("/admin") public ResponseEntity getAdmin(HttpServletRequest request) { - // TODO: role이 admin이면 "Hello, admin" 반환하기 String role = (String) request.getAttribute("role"); if (role != null && role.equals("ROLE_ADMIN")) { return ResponseEntity.ok("Hello, admin"); diff --git a/src/main/java/com/kuit/kuit4serverauth/dto/LoginRequest.java b/src/main/java/com/kuit/kuit4serverauth/dto/LoginRequest.java new file mode 100644 index 0000000..4a5b289 --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/dto/LoginRequest.java @@ -0,0 +1,12 @@ +package com.kuit.kuit4serverauth.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class LoginRequest { + + private String username; + private String password; +} diff --git a/src/main/java/com/kuit/kuit4serverauth/dto/LoginResponse.java b/src/main/java/com/kuit/kuit4serverauth/dto/LoginResponse.java new file mode 100644 index 0000000..89075ef --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/dto/LoginResponse.java @@ -0,0 +1,17 @@ +package com.kuit.kuit4serverauth.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class LoginResponse { + + private String accessToken; + private String refreshToken; + + public LoginResponse(String accessToken, String refreshToken) { + this.accessToken = accessToken; + this.refreshToken = refreshToken; + } +} diff --git a/src/main/java/com/kuit/kuit4serverauth/dto/TokenResponse.java b/src/main/java/com/kuit/kuit4serverauth/dto/TokenResponse.java new file mode 100644 index 0000000..b4ab0fd --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/dto/TokenResponse.java @@ -0,0 +1,15 @@ +package com.kuit.kuit4serverauth.dto; + +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +public class TokenResponse { + + private String accessToken; + + public TokenResponse(String accessToken) { + this.accessToken = accessToken; + } +} diff --git a/src/main/java/com/kuit/kuit4serverauth/service/JwtUtil.java b/src/main/java/com/kuit/kuit4serverauth/service/JwtUtil.java index 928516b..abdba8b 100644 --- a/src/main/java/com/kuit/kuit4serverauth/service/JwtUtil.java +++ b/src/main/java/com/kuit/kuit4serverauth/service/JwtUtil.java @@ -18,6 +18,9 @@ public class JwtUtil { @Value("${jwt.expiration}") private long expirationMs; // 1 hour + @Value("${jwt.refresh-expiration}") + private long refreshExpirationMs; + public String generateToken(String username, String role) { return Jwts.builder() .setSubject(username) @@ -28,6 +31,15 @@ public String generateToken(String username, String role) { .compact(); } + public String generateRefreshToken(String username) { + return Jwts.builder() + .setSubject(username) + .setIssuedAt(new Date()) + .setExpiration(new Date(System.currentTimeMillis() + refreshExpirationMs)) + .signWith(SignatureAlgorithm.HS256, secret) + .compact(); + } + public Claims validateToken(String token) { try { return Jwts.parser() diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 01c5197..7120b1c 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -14,5 +14,7 @@ spring: jwt: secret: mysecretkey01234567890123456789012345678901234 - expiration: 3600000 + expiration: 100000 + refresh-expiration: 60480000 + From e2a74cd44728bab4b6c86603f052c131dc1f51eb Mon Sep 17 00:00:00 2001 From: ksg Date: Tue, 19 Nov 2024 00:27:45 +0900 Subject: [PATCH 3/6] =?UTF-8?q?feat:=20Argument=20Resolver=20=EC=B6=94?= =?UTF-8?q?=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RoleArgumentResolver.java | 25 +++++++++++++++++++ .../UsernameArgumentResolver.java | 25 +++++++++++++++++++ .../kuit4serverauth/config/WebConfig.java | 20 +++++++++++++-- .../controller/UserController.java | 7 +++--- 4 files changed, 71 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/kuit/kuit4serverauth/argumentResolver/RoleArgumentResolver.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/argumentResolver/UsernameArgumentResolver.java diff --git a/src/main/java/com/kuit/kuit4serverauth/argumentResolver/RoleArgumentResolver.java b/src/main/java/com/kuit/kuit4serverauth/argumentResolver/RoleArgumentResolver.java new file mode 100644 index 0000000..7a264ae --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/argumentResolver/RoleArgumentResolver.java @@ -0,0 +1,25 @@ +package com.kuit.kuit4serverauth.argumentResolver; + +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.core.MethodParameter; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +@Component +public class RoleArgumentResolver implements HandlerMethodArgumentResolver { + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.getParameterType().equals(String.class) && + parameter.getParameterName().equals("role"); + } + + @Override + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { + + HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); + return request.getAttribute("role"); + } +} diff --git a/src/main/java/com/kuit/kuit4serverauth/argumentResolver/UsernameArgumentResolver.java b/src/main/java/com/kuit/kuit4serverauth/argumentResolver/UsernameArgumentResolver.java new file mode 100644 index 0000000..dd67d25 --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/argumentResolver/UsernameArgumentResolver.java @@ -0,0 +1,25 @@ +package com.kuit.kuit4serverauth.argumentResolver; + +import jakarta.servlet.http.HttpServletRequest; +import org.springframework.core.MethodParameter; +import org.springframework.stereotype.Component; +import org.springframework.web.bind.support.WebDataBinderFactory; +import org.springframework.web.context.request.NativeWebRequest; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; +import org.springframework.web.method.support.ModelAndViewContainer; + +@Component +public class UsernameArgumentResolver implements HandlerMethodArgumentResolver { + @Override + public boolean supportsParameter(MethodParameter parameter) { + return parameter.getParameterType().equals(String.class) && + parameter.getParameterName().equals("username"); + } + + @Override + public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { + + HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); + return request.getAttribute("username"); + } +} diff --git a/src/main/java/com/kuit/kuit4serverauth/config/WebConfig.java b/src/main/java/com/kuit/kuit4serverauth/config/WebConfig.java index 86b86ce..bffd929 100644 --- a/src/main/java/com/kuit/kuit4serverauth/config/WebConfig.java +++ b/src/main/java/com/kuit/kuit4serverauth/config/WebConfig.java @@ -1,23 +1,39 @@ package com.kuit.kuit4serverauth.config; +import com.kuit.kuit4serverauth.argumentResolver.RoleArgumentResolver; +import com.kuit.kuit4serverauth.argumentResolver.UsernameArgumentResolver; import com.kuit.kuit4serverauth.interceptor.AuthInterceptor; import org.springframework.context.annotation.Configuration; +import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; +import java.util.List; + @Configuration public class WebConfig implements WebMvcConfigurer { private final AuthInterceptor authInterceptor; + private final UsernameArgumentResolver usernameArgumentResolver; + private final RoleArgumentResolver roleArgumentResolver; - public WebConfig(AuthInterceptor authInterceptor) { + public WebConfig(AuthInterceptor authInterceptor, + UsernameArgumentResolver usernameArgumentResolver, + RoleArgumentResolver roleArgumentResolver) { this.authInterceptor = authInterceptor; + this.usernameArgumentResolver = usernameArgumentResolver; + this.roleArgumentResolver = roleArgumentResolver; } @Override public void addInterceptors(InterceptorRegistry registry) { - // TODO /profile, /admin 앞에 붙이기 registry.addInterceptor(authInterceptor) .addPathPatterns("/profile") .addPathPatterns("/admin"); } + + @Override + public void addArgumentResolvers(List argumentResolvers) { + argumentResolvers.add(usernameArgumentResolver); + argumentResolvers.add(roleArgumentResolver); + } } diff --git a/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java b/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java index d58285a..fed4395 100644 --- a/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java +++ b/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java @@ -5,14 +5,14 @@ import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestAttribute; import org.springframework.web.bind.annotation.RestController; @RestController public class UserController { @GetMapping("/profile") - public ResponseEntity getProfile(HttpServletRequest request) { - String username = (String) request.getAttribute("username"); + public ResponseEntity getProfile(@RequestAttribute("username") String username) { if (username != null) { return ResponseEntity.ok("Hello, " + username); @@ -22,8 +22,7 @@ public ResponseEntity getProfile(HttpServletRequest request) { } @GetMapping("/admin") - public ResponseEntity getAdmin(HttpServletRequest request) { - String role = (String) request.getAttribute("role"); + public ResponseEntity getAdmin(@RequestAttribute("role") String role) { if (role != null && role.equals("ROLE_ADMIN")) { return ResponseEntity.ok("Hello, admin"); } From 3195fe82273afeb013ec9a78fa2e77636e13a674 Mon Sep 17 00:00:00 2001 From: ksg Date: Wed, 20 Nov 2024 20:58:44 +0900 Subject: [PATCH 4/6] =?UTF-8?q?refactor:=20refresh-token-rotation=20?= =?UTF-8?q?=EB=8F=84=EC=9E=85=20=EB=B0=8F=20repository=20=EB=8F=84?= =?UTF-8?q?=EC=9E=85.=20+=20dto=20=EC=88=98=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../RoleArgumentResolver.java | 25 ------- ...ver.java => UserInfoArgumentResolver.java} | 10 +-- .../kuit4serverauth/config/WebConfig.java | 15 ++--- .../controller/AuthController.java | 50 +++----------- .../controller/UserController.java | 16 +++-- .../kuit4serverauth/dto/LoginResponse.java | 17 ----- .../kuit/kuit4serverauth/dto/TokenDTO.java | 12 ++++ .../kuit4serverauth/dto/TokenResponse.java | 15 ----- .../kuit/kuit4serverauth/dto/UserInfo.java | 13 ++++ .../kuit4serverauth/exception/ErrorCode.java | 1 + .../repository/RefreshTokenRepository.java | 31 +++++++++ .../kuit4serverauth/service/AuthService.java | 66 +++++++++++++++++++ .../kuit/kuit4serverauth/service/JwtUtil.java | 4 +- src/main/resources/schema.sql | 6 ++ 14 files changed, 160 insertions(+), 121 deletions(-) delete mode 100644 src/main/java/com/kuit/kuit4serverauth/argumentResolver/RoleArgumentResolver.java rename src/main/java/com/kuit/kuit4serverauth/argumentResolver/{UsernameArgumentResolver.java => UserInfoArgumentResolver.java} (71%) delete mode 100644 src/main/java/com/kuit/kuit4serverauth/dto/LoginResponse.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/dto/TokenDTO.java delete mode 100644 src/main/java/com/kuit/kuit4serverauth/dto/TokenResponse.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/dto/UserInfo.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/repository/RefreshTokenRepository.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/service/AuthService.java diff --git a/src/main/java/com/kuit/kuit4serverauth/argumentResolver/RoleArgumentResolver.java b/src/main/java/com/kuit/kuit4serverauth/argumentResolver/RoleArgumentResolver.java deleted file mode 100644 index 7a264ae..0000000 --- a/src/main/java/com/kuit/kuit4serverauth/argumentResolver/RoleArgumentResolver.java +++ /dev/null @@ -1,25 +0,0 @@ -package com.kuit.kuit4serverauth.argumentResolver; - -import jakarta.servlet.http.HttpServletRequest; -import org.springframework.core.MethodParameter; -import org.springframework.stereotype.Component; -import org.springframework.web.bind.support.WebDataBinderFactory; -import org.springframework.web.context.request.NativeWebRequest; -import org.springframework.web.method.support.HandlerMethodArgumentResolver; -import org.springframework.web.method.support.ModelAndViewContainer; - -@Component -public class RoleArgumentResolver implements HandlerMethodArgumentResolver { - @Override - public boolean supportsParameter(MethodParameter parameter) { - return parameter.getParameterType().equals(String.class) && - parameter.getParameterName().equals("role"); - } - - @Override - public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { - - HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); - return request.getAttribute("role"); - } -} diff --git a/src/main/java/com/kuit/kuit4serverauth/argumentResolver/UsernameArgumentResolver.java b/src/main/java/com/kuit/kuit4serverauth/argumentResolver/UserInfoArgumentResolver.java similarity index 71% rename from src/main/java/com/kuit/kuit4serverauth/argumentResolver/UsernameArgumentResolver.java rename to src/main/java/com/kuit/kuit4serverauth/argumentResolver/UserInfoArgumentResolver.java index dd67d25..dd72a11 100644 --- a/src/main/java/com/kuit/kuit4serverauth/argumentResolver/UsernameArgumentResolver.java +++ b/src/main/java/com/kuit/kuit4serverauth/argumentResolver/UserInfoArgumentResolver.java @@ -1,5 +1,6 @@ package com.kuit.kuit4serverauth.argumentResolver; +import com.kuit.kuit4serverauth.dto.UserInfo; import jakarta.servlet.http.HttpServletRequest; import org.springframework.core.MethodParameter; import org.springframework.stereotype.Component; @@ -9,17 +10,18 @@ import org.springframework.web.method.support.ModelAndViewContainer; @Component -public class UsernameArgumentResolver implements HandlerMethodArgumentResolver { +public class UserInfoArgumentResolver implements HandlerMethodArgumentResolver { @Override public boolean supportsParameter(MethodParameter parameter) { - return parameter.getParameterType().equals(String.class) && - parameter.getParameterName().equals("username"); + return parameter.getParameterType().equals(UserInfo.class); } @Override public Object resolveArgument(MethodParameter parameter, ModelAndViewContainer mavContainer, NativeWebRequest webRequest, WebDataBinderFactory binderFactory) throws Exception { HttpServletRequest request = webRequest.getNativeRequest(HttpServletRequest.class); - return request.getAttribute("username"); + String username = (String)request.getAttribute("username"); + String role = (String)request.getAttribute("role"); + return new UserInfo(username, role); } } diff --git a/src/main/java/com/kuit/kuit4serverauth/config/WebConfig.java b/src/main/java/com/kuit/kuit4serverauth/config/WebConfig.java index bffd929..8e1e006 100644 --- a/src/main/java/com/kuit/kuit4serverauth/config/WebConfig.java +++ b/src/main/java/com/kuit/kuit4serverauth/config/WebConfig.java @@ -1,7 +1,6 @@ package com.kuit.kuit4serverauth.config; -import com.kuit.kuit4serverauth.argumentResolver.RoleArgumentResolver; -import com.kuit.kuit4serverauth.argumentResolver.UsernameArgumentResolver; +import com.kuit.kuit4serverauth.argumentResolver.UserInfoArgumentResolver; import com.kuit.kuit4serverauth.interceptor.AuthInterceptor; import org.springframework.context.annotation.Configuration; import org.springframework.web.method.support.HandlerMethodArgumentResolver; @@ -13,15 +12,12 @@ @Configuration public class WebConfig implements WebMvcConfigurer { private final AuthInterceptor authInterceptor; - private final UsernameArgumentResolver usernameArgumentResolver; - private final RoleArgumentResolver roleArgumentResolver; + private final UserInfoArgumentResolver userInfoArgumentResolver; public WebConfig(AuthInterceptor authInterceptor, - UsernameArgumentResolver usernameArgumentResolver, - RoleArgumentResolver roleArgumentResolver) { + UserInfoArgumentResolver userInfoArgumentResolver) { this.authInterceptor = authInterceptor; - this.usernameArgumentResolver = usernameArgumentResolver; - this.roleArgumentResolver = roleArgumentResolver; + this.userInfoArgumentResolver = userInfoArgumentResolver; } @Override @@ -33,7 +29,6 @@ public void addInterceptors(InterceptorRegistry registry) { @Override public void addArgumentResolvers(List argumentResolvers) { - argumentResolvers.add(usernameArgumentResolver); - argumentResolvers.add(roleArgumentResolver); + argumentResolvers.add(userInfoArgumentResolver); } } diff --git a/src/main/java/com/kuit/kuit4serverauth/controller/AuthController.java b/src/main/java/com/kuit/kuit4serverauth/controller/AuthController.java index a5f03a2..d22d6ba 100644 --- a/src/main/java/com/kuit/kuit4serverauth/controller/AuthController.java +++ b/src/main/java/com/kuit/kuit4serverauth/controller/AuthController.java @@ -1,64 +1,32 @@ package com.kuit.kuit4serverauth.controller; import com.kuit.kuit4serverauth.dto.LoginRequest; -import com.kuit.kuit4serverauth.dto.LoginResponse; -import com.kuit.kuit4serverauth.dto.TokenResponse; -import com.kuit.kuit4serverauth.exception.CustomException; -import com.kuit.kuit4serverauth.exception.ErrorCode; -import com.kuit.kuit4serverauth.model.User; +import com.kuit.kuit4serverauth.dto.TokenDTO; import com.kuit.kuit4serverauth.repository.UserRepository; +import com.kuit.kuit4serverauth.service.AuthService; import com.kuit.kuit4serverauth.service.JwtUtil; -import io.jsonwebtoken.Claims; -import org.springframework.http.HttpStatus; +import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; -import org.springframework.web.bind.annotation.RequestParam; import org.springframework.web.bind.annotation.RestController; -import java.util.HashMap; -import java.util.Map; - @RestController +@RequiredArgsConstructor public class AuthController { private final UserRepository userRepository; private final JwtUtil jwtUtil; - - public AuthController(UserRepository userRepository, JwtUtil jwtUtil) { - this.userRepository = userRepository; - this.jwtUtil = jwtUtil; - } + private final AuthService authService; @PostMapping("/login") - public ResponseEntity login(@RequestBody LoginRequest loginRequest) { - String username = loginRequest.getUsername(); - String password = loginRequest.getPassword(); - - User user = userRepository.findByUsername(username); - if (user == null || !user.getPassword().equals(password)) { - throw new CustomException(ErrorCode.INVALID_USERNAME_OR_PASSWORD); - } - - String accessToken = jwtUtil.generateToken(user.getUsername(), user.getRole()); - String refreshToken = jwtUtil.generateRefreshToken(user.getUsername()); - - LoginResponse response = new LoginResponse(accessToken, refreshToken); - return ResponseEntity.ok(response); + public ResponseEntity login(@RequestBody LoginRequest loginRequest) { + return ResponseEntity.ok(authService.login(loginRequest)); } // 해당 url로 요청을 보내면 RefreshToken을 통해 AccessToken을 새로 발급해줌. @PostMapping("/refresh-token") - public ResponseEntity refreshToken(@RequestBody Map tokens) { - String refreshToken = tokens.get("refreshToken"); - - Claims claims = jwtUtil.validateToken(refreshToken); - String username = claims.getSubject(); - - String newAccessToken = jwtUtil.generateToken(username, (String)claims.get("role")); - - TokenResponse response = new TokenResponse(newAccessToken); - - return ResponseEntity.ok(response); + public ResponseEntity refreshToken(@RequestBody TokenDTO tokenRequest) { + return ResponseEntity.ok(authService.refresh(tokenRequest)); } } diff --git a/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java b/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java index fed4395..0eab6e2 100644 --- a/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java +++ b/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java @@ -1,7 +1,10 @@ package com.kuit.kuit4serverauth.controller; +import com.kuit.kuit4serverauth.dto.UserInfo; import com.kuit.kuit4serverauth.repository.UserRepository; import jakarta.servlet.http.HttpServletRequest; +import lombok.Setter; +import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.GetMapping; @@ -9,21 +12,20 @@ import org.springframework.web.bind.annotation.RestController; @RestController +@Slf4j public class UserController { @GetMapping("/profile") - public ResponseEntity getProfile(@RequestAttribute("username") String username) { - - if (username != null) { - return ResponseEntity.ok("Hello, " + username); + public ResponseEntity getProfile(UserInfo userInfo) { + if (userInfo.getUsername() != null) { + return ResponseEntity.ok("Hello, " + userInfo.getUsername()); } - return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body("Unauthorized"); } @GetMapping("/admin") - public ResponseEntity getAdmin(@RequestAttribute("role") String role) { - if (role != null && role.equals("ROLE_ADMIN")) { + public ResponseEntity getAdmin(UserInfo userInfo) { + if (userInfo.getRole() != null && userInfo.getRole().equals("ROLE_ADMIN")) { return ResponseEntity.ok("Hello, admin"); } return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Forbidden"); diff --git a/src/main/java/com/kuit/kuit4serverauth/dto/LoginResponse.java b/src/main/java/com/kuit/kuit4serverauth/dto/LoginResponse.java deleted file mode 100644 index 89075ef..0000000 --- a/src/main/java/com/kuit/kuit4serverauth/dto/LoginResponse.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.kuit.kuit4serverauth.dto; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class LoginResponse { - - private String accessToken; - private String refreshToken; - - public LoginResponse(String accessToken, String refreshToken) { - this.accessToken = accessToken; - this.refreshToken = refreshToken; - } -} diff --git a/src/main/java/com/kuit/kuit4serverauth/dto/TokenDTO.java b/src/main/java/com/kuit/kuit4serverauth/dto/TokenDTO.java new file mode 100644 index 0000000..020b373 --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/dto/TokenDTO.java @@ -0,0 +1,12 @@ +package com.kuit.kuit4serverauth.dto; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; + +@Getter +@RequiredArgsConstructor +public class TokenDTO { + + private final String refreshToken; + private final String accessToken; +} diff --git a/src/main/java/com/kuit/kuit4serverauth/dto/TokenResponse.java b/src/main/java/com/kuit/kuit4serverauth/dto/TokenResponse.java deleted file mode 100644 index b4ab0fd..0000000 --- a/src/main/java/com/kuit/kuit4serverauth/dto/TokenResponse.java +++ /dev/null @@ -1,15 +0,0 @@ -package com.kuit.kuit4serverauth.dto; - -import lombok.Getter; -import lombok.Setter; - -@Getter -@Setter -public class TokenResponse { - - private String accessToken; - - public TokenResponse(String accessToken) { - this.accessToken = accessToken; - } -} diff --git a/src/main/java/com/kuit/kuit4serverauth/dto/UserInfo.java b/src/main/java/com/kuit/kuit4serverauth/dto/UserInfo.java new file mode 100644 index 0000000..c046773 --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/dto/UserInfo.java @@ -0,0 +1,13 @@ +package com.kuit.kuit4serverauth.dto; + +import lombok.Getter; +import lombok.RequiredArgsConstructor; +import lombok.Setter; + +@Getter +@RequiredArgsConstructor +public class UserInfo { + + private final String username; + private final String role; +} diff --git a/src/main/java/com/kuit/kuit4serverauth/exception/ErrorCode.java b/src/main/java/com/kuit/kuit4serverauth/exception/ErrorCode.java index ed89dd3..7184c8d 100644 --- a/src/main/java/com/kuit/kuit4serverauth/exception/ErrorCode.java +++ b/src/main/java/com/kuit/kuit4serverauth/exception/ErrorCode.java @@ -3,6 +3,7 @@ public enum ErrorCode { INVALID_USERNAME_OR_PASSWORD(401, "Invalid username or password"), INVALID_TOKEN(401, "Invalid or expired token"), + INVALID_REFRESH_TOKEN(401, "Invalid or expired refresh token"), MISSING_AUTH_HEADER(401, "Missing or invalid Authorization header"), FORBIDDEN_ACCESS(403, "Access denied"), INTERNAL_SERVER_ERROR(500, "Internal server error"); diff --git a/src/main/java/com/kuit/kuit4serverauth/repository/RefreshTokenRepository.java b/src/main/java/com/kuit/kuit4serverauth/repository/RefreshTokenRepository.java new file mode 100644 index 0000000..c064589 --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/repository/RefreshTokenRepository.java @@ -0,0 +1,31 @@ +package com.kuit.kuit4serverauth.repository; + +import com.kuit.kuit4serverauth.model.User; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; + +@Repository +public class RefreshTokenRepository { + + private final JdbcTemplate jdbcTemplate; + + public RefreshTokenRepository(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + public String findByUsername(String username) { + String sql = "SELECT refreshToken FROM refreshTokens WHERE username = ?"; + return jdbcTemplate.queryForObject(sql, (rs, rowNum) -> rs.getString("refreshToken"), username); + } + + public void save(String username, String refreshToken) { + String sql = "INSERT INTO refreshTokens (username, refreshToken) VALUES (?, ?)"; + jdbcTemplate.update(sql, username, refreshToken); + } + + public void updateRefreshToken(String username, String refreshToken) { + String sql = "UPDATE refreshTokens SET refreshToken = ? WHERE username = ?"; + jdbcTemplate.update(sql, refreshToken, username); + } +} diff --git a/src/main/java/com/kuit/kuit4serverauth/service/AuthService.java b/src/main/java/com/kuit/kuit4serverauth/service/AuthService.java new file mode 100644 index 0000000..d46e996 --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/service/AuthService.java @@ -0,0 +1,66 @@ +package com.kuit.kuit4serverauth.service; + +import com.kuit.kuit4serverauth.dto.LoginRequest; +import com.kuit.kuit4serverauth.dto.TokenDTO; +import com.kuit.kuit4serverauth.exception.CustomException; +import com.kuit.kuit4serverauth.exception.ErrorCode; +import com.kuit.kuit4serverauth.model.User; +import com.kuit.kuit4serverauth.repository.RefreshTokenRepository; +import com.kuit.kuit4serverauth.repository.UserRepository; +import io.jsonwebtoken.Claims; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; +import org.springframework.web.bind.annotation.RequestBody; + +@Slf4j +@Service +@RequiredArgsConstructor +public class AuthService { + + private final JwtUtil jwtUtil; + private final UserRepository userRepository; + private final RefreshTokenRepository refreshTokenRepository; + + + public TokenDTO login(LoginRequest loginRequest) { + String username = loginRequest.getUsername(); + String password = loginRequest.getPassword(); + + User user = userRepository.findByUsername(username); + if (user == null || !user.getPassword().equals(password)) { + throw new CustomException(ErrorCode.INVALID_USERNAME_OR_PASSWORD); + } + + String accessToken = jwtUtil.generateToken(user.getUsername(), user.getRole()); + String refreshToken = jwtUtil.generateRefreshToken(user.getUsername()); + + refreshTokenRepository.save(username, refreshToken); + + return new TokenDTO(accessToken, refreshToken); + } + + public TokenDTO refresh(@RequestBody TokenDTO tokenRequest) { + String refreshToken = tokenRequest.getRefreshToken(); + + Claims claims = jwtUtil.validateToken(refreshToken); + String username = claims.getSubject(); + + String oldRefreshToken = refreshTokenRepository.findByUsername(username); + + if(!oldRefreshToken.equals(refreshToken)) { + throw new CustomException(ErrorCode.INVALID_REFRESH_TOKEN); + } + + String newAccessToken = jwtUtil.generateToken(username, (String)claims.get("role")); + + //Refresh-Token-Rotation + String newRefreshToken = jwtUtil.generateRefreshToken(username); + refreshTokenRepository.updateRefreshToken(username, newRefreshToken); + + + return new TokenDTO(newAccessToken, newRefreshToken); + } + + +} diff --git a/src/main/java/com/kuit/kuit4serverauth/service/JwtUtil.java b/src/main/java/com/kuit/kuit4serverauth/service/JwtUtil.java index abdba8b..afa3f37 100644 --- a/src/main/java/com/kuit/kuit4serverauth/service/JwtUtil.java +++ b/src/main/java/com/kuit/kuit4serverauth/service/JwtUtil.java @@ -42,8 +42,8 @@ public String generateRefreshToken(String username) { public Claims validateToken(String token) { try { - return Jwts.parser() - .setSigningKey(secret) + return Jwts.parser() // jwt 타입인지 + .setSigningKey(secret) // 내가 발급한 게 맞는지 .parseClaimsJws(token) .getBody(); } catch (Exception e) { diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index c604313..6fc78a2 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -3,4 +3,10 @@ CREATE TABLE users ( username VARCHAR(50) NOT NULL, password VARCHAR(100) NOT NULL, role VARCHAR(20) NOT NULL +); + +CREATE TABLE refreshTokens ( + id BIGINT AUTO_INCREMENT PRIMARY KEY, + username VARCHAR(50) NOT NULL, + refreshToken VARCHAR(255) NOT NULL ); \ No newline at end of file From 242042fc2712518ba7a5e86d044b24f5d1230846 Mon Sep 17 00:00:00 2001 From: ksg Date: Mon, 2 Dec 2024 22:01:17 +0900 Subject: [PATCH 5/6] =?UTF-8?q?feat:=20mysql=20=EC=97=B0=EB=8F=99=20?= =?UTF-8?q?=EC=99=84=EB=A3=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 +++ src/main/resources/application.yml | 12 ++++-------- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/build.gradle b/build.gradle index f607ed6..175beb3 100644 --- a/build.gradle +++ b/build.gradle @@ -32,6 +32,9 @@ dependencies { // H2 runtimeOnly 'com.h2database:h2' + // MySQL + runtimeOnly 'com.mysql:mysql-connector-j' + // JWT (Java JSON Web Token) implementation 'io.jsonwebtoken:jjwt-api:0.11.5' implementation 'io.jsonwebtoken:jjwt-impl:0.11.5' diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index 7120b1c..4c8ec7f 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -3,14 +3,10 @@ server: spring: datasource: - url: jdbc:h2:mem:mission_db;DB_CLOSE_DELAY=-1;MODE=MYSQL - driver-class-name: org.h2.Driver - username: sa - password: password - h2: - console: - enabled: true - path: /h2-console + url: jdbc:mysql://localhost:3306/kuit_week9?serverTimezone=Asia/Seoul&characterEncoding=UTF-8 + driver-class-name: com.mysql.cj.jdbc.Driver + username: ksg1227 + password: skcjswo00 jwt: secret: mysecretkey01234567890123456789012345678901234 From ef2b0e2443d766d5e67186b7c07bc9b716d4e98f Mon Sep 17 00:00:00 2001 From: ksg Date: Sat, 7 Dec 2024 17:32:02 +0900 Subject: [PATCH 6/6] =?UTF-8?q?feature:=2010=EC=A3=BC=EC=B0=A8=20=EB=AF=B8?= =?UTF-8?q?=EC=85=98=20=EC=88=98=ED=96=89?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- build.gradle | 3 ++ .../kuit4serverauth/config/SwaggerConfig.java | 19 +++++++ .../kuit4serverauth/config/WebConfig.java | 8 +-- .../controller/CategoryController.java | 24 +++++++++ .../controller/MenuController.java | 26 ++++++++++ .../controller/StoreController.java | 28 ++++++++++ .../controller/UserController.java | 29 ++++++++--- .../kuit4serverauth/dto/MenuStoreDTO.java | 15 ++++++ .../kuit4serverauth/dto/OrderInfoDTO.java | 18 +++++++ .../dto/StoreCategoryOrderCountDTO.java | 18 +++++++ .../kuit/kuit4serverauth/model/Category.java | 14 +++++ .../com/kuit/kuit4serverauth/model/Menu.java | 15 ++++++ .../com/kuit/kuit4serverauth/model/Order.java | 26 ++++++++++ .../com/kuit/kuit4serverauth/model/Store.java | 19 +++++++ .../com/kuit/kuit4serverauth/model/User.java | 6 ++- .../repository/CategoryRepository.java | 51 +++++++++++++++++++ .../repository/MenuRepository.java | 50 ++++++++++++++++++ .../repository/StoreRepository.java | 26 ++++++++++ .../repository/UserRepository.java | 51 ++++++++++++++++++- .../service/CategoryService.java | 20 ++++++++ .../kuit4serverauth/service/MenuService.java | 19 +++++++ .../kuit4serverauth/service/StoreService.java | 20 ++++++++ .../kuit4serverauth/service/UserService.java | 24 +++++++++ src/main/resources/data.sql | 31 +++++++++++ src/main/resources/schema.sql | 36 ++++++++++++- 25 files changed, 580 insertions(+), 16 deletions(-) create mode 100644 src/main/java/com/kuit/kuit4serverauth/config/SwaggerConfig.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/controller/CategoryController.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/controller/MenuController.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/controller/StoreController.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/dto/MenuStoreDTO.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/dto/OrderInfoDTO.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/dto/StoreCategoryOrderCountDTO.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/model/Category.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/model/Menu.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/model/Order.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/model/Store.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/repository/CategoryRepository.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/repository/MenuRepository.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/repository/StoreRepository.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/service/CategoryService.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/service/MenuService.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/service/StoreService.java create mode 100644 src/main/java/com/kuit/kuit4serverauth/service/UserService.java diff --git a/build.gradle b/build.gradle index 175beb3..28c6679 100644 --- a/build.gradle +++ b/build.gradle @@ -40,6 +40,9 @@ dependencies { implementation 'io.jsonwebtoken:jjwt-impl:0.11.5' implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5' + // Swagger + implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.5.0' + // Lombok (Optional) compileOnly 'org.projectlombok:lombok' annotationProcessor 'org.projectlombok:lombok' diff --git a/src/main/java/com/kuit/kuit4serverauth/config/SwaggerConfig.java b/src/main/java/com/kuit/kuit4serverauth/config/SwaggerConfig.java new file mode 100644 index 0000000..24d7ffd --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/config/SwaggerConfig.java @@ -0,0 +1,19 @@ +package com.kuit.kuit4serverauth.config; + +import io.swagger.v3.oas.models.info.Info; +import io.swagger.v3.oas.models.OpenAPI; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; + +@Configuration +public class SwaggerConfig { + + @Bean + public OpenAPI openAPI() { + return new OpenAPI() + .info(info); + } + + Info info = new Info().title("Kuit4 Server Auth").version("0.0.1").description( + "

Kuit4 Server Auth

"); +} diff --git a/src/main/java/com/kuit/kuit4serverauth/config/WebConfig.java b/src/main/java/com/kuit/kuit4serverauth/config/WebConfig.java index 8e1e006..3eb2413 100644 --- a/src/main/java/com/kuit/kuit4serverauth/config/WebConfig.java +++ b/src/main/java/com/kuit/kuit4serverauth/config/WebConfig.java @@ -2,6 +2,7 @@ import com.kuit.kuit4serverauth.argumentResolver.UserInfoArgumentResolver; import com.kuit.kuit4serverauth.interceptor.AuthInterceptor; +import lombok.RequiredArgsConstructor; import org.springframework.context.annotation.Configuration; import org.springframework.web.method.support.HandlerMethodArgumentResolver; import org.springframework.web.servlet.config.annotation.InterceptorRegistry; @@ -10,16 +11,11 @@ import java.util.List; @Configuration +@RequiredArgsConstructor public class WebConfig implements WebMvcConfigurer { private final AuthInterceptor authInterceptor; private final UserInfoArgumentResolver userInfoArgumentResolver; - public WebConfig(AuthInterceptor authInterceptor, - UserInfoArgumentResolver userInfoArgumentResolver) { - this.authInterceptor = authInterceptor; - this.userInfoArgumentResolver = userInfoArgumentResolver; - } - @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(authInterceptor) diff --git a/src/main/java/com/kuit/kuit4serverauth/controller/CategoryController.java b/src/main/java/com/kuit/kuit4serverauth/controller/CategoryController.java new file mode 100644 index 0000000..2f46920 --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/controller/CategoryController.java @@ -0,0 +1,24 @@ +package com.kuit.kuit4serverauth.controller; + +import com.kuit.kuit4serverauth.dto.StoreCategoryOrderCountDTO; +import com.kuit.kuit4serverauth.service.CategoryService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PathVariable; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequiredArgsConstructor +public class CategoryController { + + private final CategoryService categoryService; + + @GetMapping("/categories/{category_id}/most-ordered-store") + public ResponseEntity> getMostOrderedStoreByCategory(@PathVariable("category_id") Long category_id) { + List mostOrderedStore = categoryService.findMostOrderedStoreByCategory(category_id); + return ResponseEntity.ok(mostOrderedStore); + } +} diff --git a/src/main/java/com/kuit/kuit4serverauth/controller/MenuController.java b/src/main/java/com/kuit/kuit4serverauth/controller/MenuController.java new file mode 100644 index 0000000..d2576fd --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/controller/MenuController.java @@ -0,0 +1,26 @@ +package com.kuit.kuit4serverauth.controller; + +import com.kuit.kuit4serverauth.dto.MenuStoreDTO; +import com.kuit.kuit4serverauth.service.MenuService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequiredArgsConstructor +public class MenuController { + + private final MenuService menuService; + + @GetMapping("/menus") + public ResponseEntity> search(@RequestParam("menuName") String menuName) { + List list = menuService.findMenuAndStoreNameByMenuName(menuName); + + return ResponseEntity.ok(list); + } +} diff --git a/src/main/java/com/kuit/kuit4serverauth/controller/StoreController.java b/src/main/java/com/kuit/kuit4serverauth/controller/StoreController.java new file mode 100644 index 0000000..74937e3 --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/controller/StoreController.java @@ -0,0 +1,28 @@ +package com.kuit.kuit4serverauth.controller; + +import com.kuit.kuit4serverauth.model.Store; +import com.kuit.kuit4serverauth.service.StoreService; +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Controller; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RequestParam; +import org.springframework.web.bind.annotation.RestController; + +import java.util.List; + +@RestController +@RequiredArgsConstructor +public class StoreController { + + private final StoreService storeService; + + @GetMapping("/stores") + public ResponseEntity> getStores(@RequestParam("minimumOrderPrice") Integer minimumOrderPrice, + @RequestParam("status") String status) { + List stores = storeService.findStoresByConditions(minimumOrderPrice, status); + + return ResponseEntity.ok(stores); + } +} diff --git a/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java b/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java index 0eab6e2..ed6c009 100644 --- a/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java +++ b/src/main/java/com/kuit/kuit4serverauth/controller/UserController.java @@ -1,20 +1,24 @@ package com.kuit.kuit4serverauth.controller; +import com.kuit.kuit4serverauth.dto.OrderInfoDTO; import com.kuit.kuit4serverauth.dto.UserInfo; -import com.kuit.kuit4serverauth.repository.UserRepository; -import jakarta.servlet.http.HttpServletRequest; -import lombok.Setter; +import com.kuit.kuit4serverauth.model.Store; +import com.kuit.kuit4serverauth.service.UserService; +import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RequestAttribute; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; + +import java.util.List; @RestController @Slf4j +@RequiredArgsConstructor public class UserController { + private final UserService userService; + @GetMapping("/profile") public ResponseEntity getProfile(UserInfo userInfo) { if (userInfo.getUsername() != null) { @@ -30,4 +34,17 @@ public ResponseEntity getAdmin(UserInfo userInfo) { } return ResponseEntity.status(HttpStatus.FORBIDDEN).body("Forbidden"); } + + @GetMapping("/users/{userId}/orders") + public ResponseEntity> getUsersAllOrders(@PathVariable Long userId) { + List usersAllOrders = userService.findUsersAllOrders(userId); + return ResponseEntity.ok(usersAllOrders); + } + + @GetMapping("/users/{userId}/ordered-stores") + public ResponseEntity> getStoresWithMultipleOrders(@PathVariable Long userId, + @RequestParam("minOrderCount") int minOrderCount) { + List stores = userService.findStoresWithMultipleOrders(userId, minOrderCount); + return ResponseEntity.ok(stores); + } } diff --git a/src/main/java/com/kuit/kuit4serverauth/dto/MenuStoreDTO.java b/src/main/java/com/kuit/kuit4serverauth/dto/MenuStoreDTO.java new file mode 100644 index 0000000..09ddb34 --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/dto/MenuStoreDTO.java @@ -0,0 +1,15 @@ +package com.kuit.kuit4serverauth.dto; + +import com.kuit.kuit4serverauth.model.Menu; +import com.kuit.kuit4serverauth.model.Store; +import lombok.*; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class MenuStoreDTO { + private Store store; + private Menu menu; +} diff --git a/src/main/java/com/kuit/kuit4serverauth/dto/OrderInfoDTO.java b/src/main/java/com/kuit/kuit4serverauth/dto/OrderInfoDTO.java new file mode 100644 index 0000000..95f34cb --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/dto/OrderInfoDTO.java @@ -0,0 +1,18 @@ +package com.kuit.kuit4serverauth.dto; + +import com.kuit.kuit4serverauth.model.Order; +import lombok.*; + +@Getter +@Setter +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class OrderInfoDTO { + + Order order; + int totalPrice; + String storeName; + String menuName; + +} diff --git a/src/main/java/com/kuit/kuit4serverauth/dto/StoreCategoryOrderCountDTO.java b/src/main/java/com/kuit/kuit4serverauth/dto/StoreCategoryOrderCountDTO.java new file mode 100644 index 0000000..2b0dcf9 --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/dto/StoreCategoryOrderCountDTO.java @@ -0,0 +1,18 @@ +package com.kuit.kuit4serverauth.dto; + +import com.kuit.kuit4serverauth.model.Category; +import com.kuit.kuit4serverauth.model.Store; +import lombok.*; + +@Setter +@Getter +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class StoreCategoryOrderCountDTO { + + Store store; + Category category; + int orderCount; + +} diff --git a/src/main/java/com/kuit/kuit4serverauth/model/Category.java b/src/main/java/com/kuit/kuit4serverauth/model/Category.java new file mode 100644 index 0000000..81b543f --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/model/Category.java @@ -0,0 +1,14 @@ +package com.kuit.kuit4serverauth.model; + +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class Category { + + private Long category_id; + private String category_name; +} diff --git a/src/main/java/com/kuit/kuit4serverauth/model/Menu.java b/src/main/java/com/kuit/kuit4serverauth/model/Menu.java new file mode 100644 index 0000000..b215b9e --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/model/Menu.java @@ -0,0 +1,15 @@ +package com.kuit.kuit4serverauth.model; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Builder +public class Menu { + private Long menu_id; + private String name; + private int price; + private Long store_id; // JPA 였다면 Store store 로 매핑했을 듯 +} diff --git a/src/main/java/com/kuit/kuit4serverauth/model/Order.java b/src/main/java/com/kuit/kuit4serverauth/model/Order.java new file mode 100644 index 0000000..8702120 --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/model/Order.java @@ -0,0 +1,26 @@ +package com.kuit.kuit4serverauth.model; + +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class Order { + private Long order_id; + private int total_price; + private Long store_id; + private Long menu_id; + private Long user_id; + + // JPA 였다면 + // Store store + // Menu menu + // User user + + // 혹은 + // Store store + // List orderMenuList + // User user +} diff --git a/src/main/java/com/kuit/kuit4serverauth/model/Store.java b/src/main/java/com/kuit/kuit4serverauth/model/Store.java new file mode 100644 index 0000000..744248a --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/model/Store.java @@ -0,0 +1,19 @@ +package com.kuit.kuit4serverauth.model; + +import lombok.*; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class Store { + private Long store_id; + private String name; + private Integer minimum_order_price; + private String status; + private Long category_id; + + // JPA 였다면 + // Category category +} diff --git a/src/main/java/com/kuit/kuit4serverauth/model/User.java b/src/main/java/com/kuit/kuit4serverauth/model/User.java index 7160884..2203442 100644 --- a/src/main/java/com/kuit/kuit4serverauth/model/User.java +++ b/src/main/java/com/kuit/kuit4serverauth/model/User.java @@ -1,10 +1,12 @@ package com.kuit.kuit4serverauth.model; -import lombok.Getter; -import lombok.Setter; +import lombok.*; @Getter @Setter +@NoArgsConstructor +@AllArgsConstructor +@Builder public class User { private Long id; private String username; diff --git a/src/main/java/com/kuit/kuit4serverauth/repository/CategoryRepository.java b/src/main/java/com/kuit/kuit4serverauth/repository/CategoryRepository.java new file mode 100644 index 0000000..eb3f22e --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/repository/CategoryRepository.java @@ -0,0 +1,51 @@ +package com.kuit.kuit4serverauth.repository; + +import com.kuit.kuit4serverauth.dto.StoreCategoryOrderCountDTO; +import com.kuit.kuit4serverauth.model.Category; +import com.kuit.kuit4serverauth.model.Store; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public class CategoryRepository { + + private final JdbcTemplate jdbcTemplate; + + public CategoryRepository(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + // 특정 카테고리에서 주문이 가장 많은 상위 음식점 조회. + public List findMostOrderedStoreByCategory(Long category_id) { + String sql = "SELECT s.store_id, s.name, s.category_id, s.minimum_order_price, s.status, COUNT(o.order_id) AS orderCount, c.category_id, c.category_name " + + "FROM stores s " + + "JOIN orders o on s.store_id = o.store_id " + + "JOIN categories c on s.category_id = c.category_id " + + "WHERE s.category_id = ? " + + "GROUP BY s.store_id, s.name, s.category_id, s.minimum_order_price, s.status, c.category_id, c.category_name " + + "ORDER BY orderCount DESC"; + + return jdbcTemplate.query(sql, (rs, rowNum) -> { + Store store = Store.builder() + .store_id(rs.getLong("store_id")) + .name(rs.getString("name")) + .category_id(rs.getLong("category_id")) + .minimum_order_price(rs.getInt("minimum_order_price")) + .status(rs.getString("status")) + .build(); + + Category category = Category.builder() + .category_id(rs.getLong("category_id")) + .category_name(rs.getString("category_name")) + .build(); + + return StoreCategoryOrderCountDTO.builder() + .store(store) + .category(category) + .orderCount(rs.getInt("orderCount")) + .build(); + }, category_id); + } +} diff --git a/src/main/java/com/kuit/kuit4serverauth/repository/MenuRepository.java b/src/main/java/com/kuit/kuit4serverauth/repository/MenuRepository.java new file mode 100644 index 0000000..869cb94 --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/repository/MenuRepository.java @@ -0,0 +1,50 @@ +package com.kuit.kuit4serverauth.repository; + +import com.kuit.kuit4serverauth.dto.MenuStoreDTO; +import com.kuit.kuit4serverauth.model.Menu; +import com.kuit.kuit4serverauth.model.Store; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public class MenuRepository { + + private final JdbcTemplate jdbcTemplate; + + public MenuRepository(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + // 메뉴 이름에 특정 문자열이 포함된 메뉴와 해당 음식점을 조회. + public List findMenuAndStoreNameByMenuName(String menuName){ + String sql = "SELECT s.store_id, s.name, s.minimum_order_price, s.status, s.category_id, m.menu_id, m.name AS menuName, m.price, m.store_id " + + "FROM menus m " + + "JOIN stores s ON s.store_id = m.store_id " + + "JOIN categories c ON s.category_id = c.category_id " + + "WHERE m.name LIKE ?"; + + return jdbcTemplate.query(sql, (rs, rowNum) -> { + Store store = Store.builder() + .store_id(rs.getLong("store_id")) + .name(rs.getString("name")) + .category_id(rs.getLong("category_id")) + .minimum_order_price(rs.getInt("minimum_order_price")) + .status(rs.getString("status")) + .build(); + + Menu menu = Menu.builder() + .menu_id(rs.getLong("menu_id")) + .name(rs.getString("menuName")) + .price(rs.getInt("price")) + .store_id(rs.getLong("store_id")) + .build(); + + return MenuStoreDTO.builder() + .store(store) + .menu(menu) + .build(); + }, "%"+menuName+"%"); + } +} diff --git a/src/main/java/com/kuit/kuit4serverauth/repository/StoreRepository.java b/src/main/java/com/kuit/kuit4serverauth/repository/StoreRepository.java new file mode 100644 index 0000000..bc05d45 --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/repository/StoreRepository.java @@ -0,0 +1,26 @@ +package com.kuit.kuit4serverauth.repository; + +import com.kuit.kuit4serverauth.model.Store; +import org.springframework.jdbc.core.BeanPropertyRowMapper; +import org.springframework.jdbc.core.JdbcTemplate; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public class StoreRepository { + + private final JdbcTemplate jdbcTemplate; + + public StoreRepository(JdbcTemplate jdbcTemplate) { + this.jdbcTemplate = jdbcTemplate; + } + + // 최소 주문 금액 조건과 활성 상태(status) 조건을 만족하는 음식점 조회. + public List findByMinimumOrderPriceAndStatus(Integer minimumOrderPrice, String status){ + String sql = "SELECT * FROM stores s WHERE s.minimum_order_price >= ? AND s.status = ?"; + return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Store.class), minimumOrderPrice, status); + } + + +} diff --git a/src/main/java/com/kuit/kuit4serverauth/repository/UserRepository.java b/src/main/java/com/kuit/kuit4serverauth/repository/UserRepository.java index 8927fee..bc8412f 100644 --- a/src/main/java/com/kuit/kuit4serverauth/repository/UserRepository.java +++ b/src/main/java/com/kuit/kuit4serverauth/repository/UserRepository.java @@ -1,10 +1,13 @@ package com.kuit.kuit4serverauth.repository; -import com.kuit.kuit4serverauth.model.User; +import com.kuit.kuit4serverauth.dto.OrderInfoDTO; +import com.kuit.kuit4serverauth.model.*; import org.springframework.jdbc.core.BeanPropertyRowMapper; import org.springframework.jdbc.core.JdbcTemplate; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public class UserRepository { private final JdbcTemplate jdbcTemplate; @@ -17,4 +20,50 @@ public User findByUsername(String username) { String sql = "SELECT * FROM users WHERE username = ?"; return jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper<>(User.class), username); } + + // 특정 회원이 두 번 이상 주문한 음식점 조회 (중복 제거). + public List findStoresWithMultipleOrders(Long userId, int minOrderCount) { + String sql = "SELECT distinct s.store_id, s.name, s.category_id, s.minimum_order_price, s.status " + + "FROM stores s JOIN orders o ON s.store_id = o.store_id " + + "WHERE o.user_id = ? " + + "GROUP BY s.store_id " + + "HAVING COUNT(o.user_id) >= ?"; + + return jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(Store.class), userId, minOrderCount); + } + + public List findUsersAllOrders(Long userId) { + String sql = "SELECT o.order_id, o.total_price , o.store_id, o.user_id, SUM(o.total_price) AS total_sum, m.menu_id, " + + "s.name AS storeName, " + + "m.name AS menuName " + + "FROM orders o " + + "JOIN users u ON o.user_id = u.id " + + "JOIN stores s ON o.store_id = s.store_id " + + "JOIN menus m ON o.menu_id = m.menu_id " + + "WHERE o.user_id = ? " + + "GROUP BY o.order_id, o.total_price, o.store_id, o.user_id, m.menu_id, s.name, m.name " + + "ORDER BY o.total_price DESC"; + + + return jdbcTemplate.query(sql, new Object[]{userId}, (rs, rowNum) -> { + Order order = Order.builder() + .order_id(rs.getLong("order_id")) + .total_price(rs.getInt("total_price")) + .store_id(rs.getLong("store_id")) + .menu_id(rs.getLong("menu_id")) + .user_id(rs.getLong("user_id")) + .build(); + + OrderInfoDTO dto = OrderInfoDTO.builder() + .order(order) + .totalPrice(rs.getInt("total_sum")) + .storeName(rs.getString("storeName")) + .menuName(rs.getString("menuName")) + .build(); + return dto; // Return the DTO + }); + } + + + } diff --git a/src/main/java/com/kuit/kuit4serverauth/service/CategoryService.java b/src/main/java/com/kuit/kuit4serverauth/service/CategoryService.java new file mode 100644 index 0000000..49c5731 --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/service/CategoryService.java @@ -0,0 +1,20 @@ +package com.kuit.kuit4serverauth.service; + +import com.kuit.kuit4serverauth.dto.StoreCategoryOrderCountDTO; +import com.kuit.kuit4serverauth.repository.CategoryRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class CategoryService { + + private final CategoryRepository categoryRepository; + + public List findMostOrderedStoreByCategory(Long category_id) { + return categoryRepository.findMostOrderedStoreByCategory(category_id); + } + +} diff --git a/src/main/java/com/kuit/kuit4serverauth/service/MenuService.java b/src/main/java/com/kuit/kuit4serverauth/service/MenuService.java new file mode 100644 index 0000000..7a6e1bf --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/service/MenuService.java @@ -0,0 +1,19 @@ +package com.kuit.kuit4serverauth.service; + +import com.kuit.kuit4serverauth.dto.MenuStoreDTO; +import com.kuit.kuit4serverauth.repository.MenuRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class MenuService { + + private final MenuRepository menuRepository; + + public List findMenuAndStoreNameByMenuName(String menuName) { + return menuRepository.findMenuAndStoreNameByMenuName(menuName); + } +} diff --git a/src/main/java/com/kuit/kuit4serverauth/service/StoreService.java b/src/main/java/com/kuit/kuit4serverauth/service/StoreService.java new file mode 100644 index 0000000..684d6d1 --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/service/StoreService.java @@ -0,0 +1,20 @@ +package com.kuit.kuit4serverauth.service; + +import com.kuit.kuit4serverauth.model.Store; +import com.kuit.kuit4serverauth.repository.StoreRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class StoreService { + + private final StoreRepository storeRepository; + + public List findStoresByConditions(Integer minimumOrderPrice, String status){ + return storeRepository.findByMinimumOrderPriceAndStatus(minimumOrderPrice, status); + } + +} diff --git a/src/main/java/com/kuit/kuit4serverauth/service/UserService.java b/src/main/java/com/kuit/kuit4serverauth/service/UserService.java new file mode 100644 index 0000000..a89147b --- /dev/null +++ b/src/main/java/com/kuit/kuit4serverauth/service/UserService.java @@ -0,0 +1,24 @@ +package com.kuit.kuit4serverauth.service; + +import com.kuit.kuit4serverauth.dto.OrderInfoDTO; +import com.kuit.kuit4serverauth.model.Store; +import com.kuit.kuit4serverauth.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.List; + +@Service +@RequiredArgsConstructor +public class UserService { + + private final UserRepository userRepository; + + public List findUsersAllOrders(Long userId) { + return userRepository.findUsersAllOrders(userId); + } + + public List findStoresWithMultipleOrders(Long userId, int minOrderCount) { + return userRepository.findStoresWithMultipleOrders(userId, minOrderCount); + } +} diff --git a/src/main/resources/data.sql b/src/main/resources/data.sql index 33ae371..35a7310 100644 --- a/src/main/resources/data.sql +++ b/src/main/resources/data.sql @@ -1,2 +1,33 @@ INSERT INTO users (username, password, role) VALUES ('admin', 'admin123', 'ROLE_ADMIN'); INSERT INTO users (username, password, role) VALUES ('user', 'user123', 'ROLE_USER'); +INSERT INTO categories (category_name) VALUES ('분식'); +INSERT INTO categories (category_name) VALUES ('중식'); +INSERT INTO categories (category_name) VALUES ('한식'); +INSERT INTO stores (name, minimum_order_price, status, category_id) VALUES ('교촌치킨', 10000, 'activated', 1); +INSERT INTO stores (name, minimum_order_price, status, category_id) VALUES ('bbq치킨', 9000, 'activated', 1); +INSERT INTO stores (name, minimum_order_price, status, category_id) VALUES ('bhc치킨', 12000, 'deactivated', 1); +INSERT INTO stores (name, minimum_order_price, status, category_id) VALUES ('중경마라', 12000, 'deactivated', 2); +INSERT INTO stores (name, minimum_order_price, status, category_id) VALUES ('홍콩반점', 6000, 'deactivated', 2); +INSERT INTO menus (name, price, store_id) VALUES ('떡볶이1', 5000, 1); +INSERT INTO menus (name, price, store_id) VALUES ('떡볶이2', 3000, 2); +INSERT INTO menus (name, price, store_id) VALUES ('떡볶이3', 3000, 3); +INSERT INTO menus (name, price, store_id) VALUES ('짜장면', 7000, 4); +INSERT INTO menus (name, price, store_id) VALUES ('짜장면', 7000, 5); +INSERT INTO orders (total_price, store_id, menu_id, user_id) VALUES (10000, 1, 1, 1); +INSERT INTO orders (total_price, store_id, menu_id, user_id) VALUES (20000, 2, 2, 1); +INSERT INTO orders (total_price, store_id, menu_id, user_id) VALUES (30000, 3, 3, 1); +INSERT INTO orders (total_price, store_id, menu_id, user_id) VALUES (40000, 1, 1, 1); +INSERT INTO orders (total_price, store_id, menu_id, user_id) VALUES (40000, 2, 2, 2); +INSERT INTO orders (total_price, store_id, menu_id, user_id) VALUES (40000, 2, 2, 2); +INSERT INTO orders (total_price, store_id, menu_id, user_id) VALUES (40000, 3, 3, 2); +INSERT INTO orders (total_price, store_id, menu_id, user_id) VALUES (10000, 2, 2, 2); +INSERT INTO orders (total_price, store_id, menu_id, user_id) VALUES (30000, 2, 2, 2); +INSERT INTO orders (total_price, store_id, menu_id, user_id) VALUES (60000, 3, 3, 2); +INSERT INTO orders (total_price, store_id, menu_id, user_id) VALUES (30000, 4, 4, 2); +INSERT INTO orders (total_price, store_id, menu_id, user_id) VALUES (30000, 4, 4, 2); +INSERT INTO orders (total_price, store_id, menu_id, user_id) VALUES (30000, 4, 4, 2); +INSERT INTO orders (total_price, store_id, menu_id, user_id) VALUES (30000, 5, 5, 1); +INSERT INTO orders (total_price, store_id, menu_id, user_id) VALUES (30000, 5, 5, 1); + + + diff --git a/src/main/resources/schema.sql b/src/main/resources/schema.sql index 6fc78a2..42af746 100644 --- a/src/main/resources/schema.sql +++ b/src/main/resources/schema.sql @@ -9,4 +9,38 @@ CREATE TABLE refreshTokens ( id BIGINT AUTO_INCREMENT PRIMARY KEY, username VARCHAR(50) NOT NULL, refreshToken VARCHAR(255) NOT NULL -); \ No newline at end of file +); + +CREATE TABLE categories ( + category_id BIGINT AUTO_INCREMENT PRIMARY KEY, + category_name VARCHAR(50) NOT NULL +); + +CREATE TABLE stores ( + store_id BIGINT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(100) NOT NULL, + minimum_order_price INTEGER, + status VARCHAR(50) NOT NULL, + category_id BIGINT, + FOREIGN KEY (category_id) REFERENCES categories(category_id) +); + +CREATE TABLE menus ( + menu_id BIGINT AUTO_INCREMENT PRIMARY KEY, + name VARCHAR(100) NOT NULL, + price INT default 0, + store_id BIGINT, + FOREIGN KEY (store_id) REFERENCES stores(store_id) +); + +CREATE TABLE orders ( + order_id BIGINT AUTO_INCREMENT PRIMARY KEY, + total_price INT default 0, + store_id BIGINT, + menu_id BIGINT, + user_id BIGINT, + FOREIGN KEY (store_id) REFERENCES stores(store_id), + FOREIGN KEY (menu_id) REFERENCES menus(menu_id), + FOREIGN KEY (user_id) REFERENCES users(id) +); +