diff --git a/DDANZI_Server_yml b/DDANZI_Server_yml index 08df0935..8912613f 160000 --- a/DDANZI_Server_yml +++ b/DDANZI_Server_yml @@ -1 +1 @@ -Subproject commit 08df093502327ec7bf86f1dfc54945093d2a3cb4 +Subproject commit 8912613fdfde0c13ecf1d5bf62cf28571f1a3f57 diff --git a/build.gradle b/build.gradle index e3d789d7..38b23179 100644 --- a/build.gradle +++ b/build.gradle @@ -23,17 +23,21 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' + //lombok + compileOnly 'org.projectlombok:lombok' + annotationProcessor 'org.projectlombok:lombok' //jpa implementation 'org.springframework.boot:spring-boot-starter-data-jpa' // mysql implementation 'mysql:mysql-connector-java:8.0.32' //redis implementation 'org.springframework.boot:spring-boot-starter-data-redis' - - //lombok - compileOnly 'org.projectlombok:lombok' - annotationProcessor 'org.projectlombok:lombok' - + // security + implementation 'org.springframework.boot:spring-boot-starter-security' + //jwt + implementation 'io.jsonwebtoken:jjwt-api:0.11.5' + implementation 'io.jsonwebtoken:jjwt-impl:0.11.5' + implementation 'io.jsonwebtoken:jjwt-jackson:0.11.5' testImplementation 'org.springframework.boot:spring-boot-starter-test' } diff --git a/src/main/java/co/orange/ddanzi/controller/AuthController.java b/src/main/java/co/orange/ddanzi/controller/AuthController.java new file mode 100644 index 00000000..f1813314 --- /dev/null +++ b/src/main/java/co/orange/ddanzi/controller/AuthController.java @@ -0,0 +1,22 @@ +package co.orange.ddanzi.controller; + +import co.orange.ddanzi.dto.auth.LoginDto; +import co.orange.ddanzi.global.common.response.ApiResponse; +import co.orange.ddanzi.service.AuthService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RequestBody; +import org.springframework.web.bind.annotation.RequestMapping; +import org.springframework.web.bind.annotation.RestController; + +@RequiredArgsConstructor +@RestController +@RequestMapping("/api/v1/auth") +public class AuthController { + private final AuthService authService; + + @PostMapping("/signin/test") + ApiResponse signin(@RequestBody LoginDto requestDto){ + return authService.testSignin(requestDto.getIdToken()); + } +} diff --git a/src/main/java/co/orange/ddanzi/controller/ItemController.java b/src/main/java/co/orange/ddanzi/controller/ItemController.java index f11aac42..9c60ca79 100644 --- a/src/main/java/co/orange/ddanzi/controller/ItemController.java +++ b/src/main/java/co/orange/ddanzi/controller/ItemController.java @@ -3,7 +3,7 @@ import co.orange.ddanzi.domain.user.User; import co.orange.ddanzi.dto.item.ConfirmProductRequestDto; import co.orange.ddanzi.dto.item.SaveItemRequestDto; -import co.orange.ddanzi.global.common.exception.Error; +import co.orange.ddanzi.global.common.error.Error; import co.orange.ddanzi.global.common.response.ApiResponse; import co.orange.ddanzi.repository.AddressRepository; import co.orange.ddanzi.repository.UserRepository; diff --git a/src/main/java/co/orange/ddanzi/controller/SettingController.java b/src/main/java/co/orange/ddanzi/controller/SettingController.java index 3936097f..15e340de 100644 --- a/src/main/java/co/orange/ddanzi/controller/SettingController.java +++ b/src/main/java/co/orange/ddanzi/controller/SettingController.java @@ -19,6 +19,11 @@ ApiResponse getSetting(){ return settingService.getSetting(); } + @GetMapping("/address/enter") + ApiResponse enterAddress(){ + return settingService.enterAddress(); + } + @GetMapping("/address") ApiResponse getAddress(){ return settingService.getAddress(); diff --git a/src/main/java/co/orange/ddanzi/domain/user/Address.java b/src/main/java/co/orange/ddanzi/domain/user/Address.java index bc98a86a..5f99537a 100644 --- a/src/main/java/co/orange/ddanzi/domain/user/Address.java +++ b/src/main/java/co/orange/ddanzi/domain/user/Address.java @@ -18,6 +18,12 @@ public class Address { @Column(name = "address_id") private Long id; //주소 고유 ID + @Column(name = "recipient") + private String recipient; + + @Column(name = "recipient_phone") + private String recipientPhone; + @Column(name = "zip_code", nullable = false, length = 5) private String zipCode; //우편번호 @@ -36,8 +42,10 @@ public class Address { private User user; //회원:주소=1:N @Builder - public Address(String zipCode, AddressType type, String address, String detailAddress, User user) { + public Address(String zipCode, String recipient, String recipientPhone, AddressType type, String address, String detailAddress, User user) { this.zipCode = zipCode; + this.recipient = recipient; + this.recipientPhone = recipientPhone; this.type = type; this.address = address; this.detailAddress = detailAddress; @@ -46,6 +54,8 @@ public Address(String zipCode, AddressType type, String address, String detailAd public void update(AddressRequestDto requestDto){ this.zipCode = requestDto.getZipCode(); + this.recipient = requestDto.getRecipient(); + this.recipientPhone = requestDto.getRecipientPhone(); this.type = requestDto.getType(); this.address = requestDto.getAddress(); this.detailAddress = requestDto.getDetailAddress(); diff --git a/src/main/java/co/orange/ddanzi/dto/ProductInfo.java b/src/main/java/co/orange/ddanzi/dto/ProductInfo.java index e7cf2381..f1533574 100644 --- a/src/main/java/co/orange/ddanzi/dto/ProductInfo.java +++ b/src/main/java/co/orange/ddanzi/dto/ProductInfo.java @@ -13,4 +13,5 @@ public class ProductInfo { private Integer originPrice; private Integer salePrice; private Integer interestCount; + private Boolean isInterested; } diff --git a/src/main/java/co/orange/ddanzi/dto/auth/AuthResponseDto.java b/src/main/java/co/orange/ddanzi/dto/auth/AuthResponseDto.java new file mode 100644 index 00000000..a40ad46a --- /dev/null +++ b/src/main/java/co/orange/ddanzi/dto/auth/AuthResponseDto.java @@ -0,0 +1,11 @@ +package co.orange.ddanzi.dto.auth; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class AuthResponseDto { + private String accesstoken; + private String nickname; +} diff --git a/src/main/java/co/orange/ddanzi/dto/auth/LoginDto.java b/src/main/java/co/orange/ddanzi/dto/auth/LoginDto.java new file mode 100644 index 00000000..08d6a44c --- /dev/null +++ b/src/main/java/co/orange/ddanzi/dto/auth/LoginDto.java @@ -0,0 +1,11 @@ +package co.orange.ddanzi.dto.auth; + +import co.orange.ddanzi.domain.user.enums.LoginType; +import lombok.Getter; + +@Getter +public class LoginDto { + private String idToken; + private LoginType type; + +} diff --git a/src/main/java/co/orange/ddanzi/dto/setting/AddressRequestDto.java b/src/main/java/co/orange/ddanzi/dto/setting/AddressRequestDto.java index 9e729828..b19944c3 100644 --- a/src/main/java/co/orange/ddanzi/dto/setting/AddressRequestDto.java +++ b/src/main/java/co/orange/ddanzi/dto/setting/AddressRequestDto.java @@ -7,6 +7,8 @@ @Getter public class AddressRequestDto { + private String recipient; + private String recipientPhone; private String zipCode; private AddressType type; private String address; @@ -15,6 +17,8 @@ public class AddressRequestDto { public Address toEntity(User user){ return Address.builder() .user(user) + .recipient(recipient) + .recipientPhone(recipientPhone) .zipCode(zipCode) .type(type) .address(address) diff --git a/src/main/java/co/orange/ddanzi/dto/setting/AddressResponseDto.java b/src/main/java/co/orange/ddanzi/dto/setting/AddressResponseDto.java index e5ae7f60..d3a5b122 100644 --- a/src/main/java/co/orange/ddanzi/dto/setting/AddressResponseDto.java +++ b/src/main/java/co/orange/ddanzi/dto/setting/AddressResponseDto.java @@ -8,10 +8,10 @@ @Builder public class AddressResponseDto { private Long addressId; - private String name; + private String recipient; private String zipCode; private AddressType type; private String address; private String detailAddress; - private String phone; + private String recipientPhone; } diff --git a/src/main/java/co/orange/ddanzi/dto/setting/EnterAddressResponseDto.java b/src/main/java/co/orange/ddanzi/dto/setting/EnterAddressResponseDto.java new file mode 100644 index 00000000..d907b793 --- /dev/null +++ b/src/main/java/co/orange/ddanzi/dto/setting/EnterAddressResponseDto.java @@ -0,0 +1,11 @@ +package co.orange.ddanzi.dto.setting; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class EnterAddressResponseDto { + private String name; + private String phone; +} diff --git a/src/main/java/co/orange/ddanzi/global/common/exception/Error.java b/src/main/java/co/orange/ddanzi/global/common/error/Error.java similarity index 82% rename from src/main/java/co/orange/ddanzi/global/common/exception/Error.java rename to src/main/java/co/orange/ddanzi/global/common/error/Error.java index a935cce4..2686c2da 100644 --- a/src/main/java/co/orange/ddanzi/global/common/exception/Error.java +++ b/src/main/java/co/orange/ddanzi/global/common/error/Error.java @@ -1,4 +1,4 @@ -package co.orange.ddanzi.global.common.exception; +package co.orange.ddanzi.global.common.error; import lombok.AccessLevel; import lombok.AllArgsConstructor; @@ -16,13 +16,17 @@ public enum Error { DUE_DATE_IS_INCORRECT(HttpStatus.BAD_REQUEST, "The due date is incorrect."), // 401 UNAUTHORIZED - + INVALID_JWT_EXCEPTION(HttpStatus.UNAUTHORIZED, "Invalid JWT"), + LOG_OUT_JWT_TOKEN(HttpStatus.UNAUTHORIZED,"Logged out user"), + JWT_EXPIRED(HttpStatus.UNAUTHORIZED,"JWT expired"), + JWT_TOKEN_NOT_EXISTS(HttpStatus.UNAUTHORIZED,"JWT value does not exist in header"), // 403 Forbidden // 404 NOT FOUND AUTHENTICATION_INFO_NOT_FOUND(HttpStatus.NOT_FOUND, "The Authentication of user does not exist."), + USER_NOT_FOUND(HttpStatus.NOT_FOUND, "User does not exist."), PRODUCT_NOT_FOUND(HttpStatus.NOT_FOUND, "The product does not exist."), CATEGORY_NOT_FOUND(HttpStatus.NOT_FOUND, "The category of the product does not exist."), DISCOUNT_INFO_NOT_FOUND(HttpStatus.NOT_FOUND, "The discount info of the category does not exist."), diff --git a/src/main/java/co/orange/ddanzi/global/common/exception/ErrorResponse.java b/src/main/java/co/orange/ddanzi/global/common/error/ErrorResponse.java similarity index 97% rename from src/main/java/co/orange/ddanzi/global/common/exception/ErrorResponse.java rename to src/main/java/co/orange/ddanzi/global/common/error/ErrorResponse.java index 489c84a8..cfa70871 100644 --- a/src/main/java/co/orange/ddanzi/global/common/exception/ErrorResponse.java +++ b/src/main/java/co/orange/ddanzi/global/common/error/ErrorResponse.java @@ -1,4 +1,4 @@ -package co.orange.ddanzi.global.common.exception; +package co.orange.ddanzi.global.common.error; import com.fasterxml.jackson.annotation.JsonFormat; import jakarta.servlet.http.HttpServletRequest; diff --git a/src/main/java/co/orange/ddanzi/global/common/exception/ApiException.java b/src/main/java/co/orange/ddanzi/global/common/exception/ApiException.java new file mode 100644 index 00000000..6ee07f01 --- /dev/null +++ b/src/main/java/co/orange/ddanzi/global/common/exception/ApiException.java @@ -0,0 +1,18 @@ +package co.orange.ddanzi.global.common.exception; + +import co.orange.ddanzi.global.common.error.Error; +import lombok.Getter; + +@Getter +public class ApiException extends RuntimeException { + private final Error error; + + public ApiException(Error error){ + super(error.getMessage()); + this.error = error; + } + + public int getHttpStatus(){ + return error.getHttpStatusCode(); + } +} \ No newline at end of file diff --git a/src/main/java/co/orange/ddanzi/global/common/exception/UnauthorizedException.java b/src/main/java/co/orange/ddanzi/global/common/exception/UnauthorizedException.java new file mode 100644 index 00000000..b1043e0a --- /dev/null +++ b/src/main/java/co/orange/ddanzi/global/common/exception/UnauthorizedException.java @@ -0,0 +1,9 @@ +package co.orange.ddanzi.global.common.exception; + +import co.orange.ddanzi.global.common.error.Error; + +public class UnauthorizedException extends ApiException{ + public UnauthorizedException(Error error) { + super(error); + } +} \ No newline at end of file diff --git a/src/main/java/co/orange/ddanzi/global/common/exception/UserNotFoundException.java b/src/main/java/co/orange/ddanzi/global/common/exception/UserNotFoundException.java new file mode 100644 index 00000000..0f002fc3 --- /dev/null +++ b/src/main/java/co/orange/ddanzi/global/common/exception/UserNotFoundException.java @@ -0,0 +1,9 @@ +package co.orange.ddanzi.global.common.exception; + +import co.orange.ddanzi.global.common.error.Error; + +public class UserNotFoundException extends ApiException{ + public UserNotFoundException() { + super(Error.USER_NOT_FOUND); + } +} \ No newline at end of file diff --git a/src/main/java/co/orange/ddanzi/global/common/response/ApiResponse.java b/src/main/java/co/orange/ddanzi/global/common/response/ApiResponse.java index afa70069..0da8b88c 100644 --- a/src/main/java/co/orange/ddanzi/global/common/response/ApiResponse.java +++ b/src/main/java/co/orange/ddanzi/global/common/response/ApiResponse.java @@ -1,6 +1,6 @@ package co.orange.ddanzi.global.common.response; -import co.orange.ddanzi.global.common.exception.Error; +import co.orange.ddanzi.global.common.error.Error; import co.orange.ddanzi.global.config.handler.GlobalControllerHandler; import com.fasterxml.jackson.annotation.JsonFormat; import com.fasterxml.jackson.annotation.JsonProperty; diff --git a/src/main/java/co/orange/ddanzi/global/config/handler/GlobalExceptionHandler.java b/src/main/java/co/orange/ddanzi/global/config/handler/GlobalExceptionHandler.java index e64155b5..62e6247e 100644 --- a/src/main/java/co/orange/ddanzi/global/config/handler/GlobalExceptionHandler.java +++ b/src/main/java/co/orange/ddanzi/global/config/handler/GlobalExceptionHandler.java @@ -1,7 +1,7 @@ package co.orange.ddanzi.global.config.handler; -import co.orange.ddanzi.global.common.exception.Error; -import co.orange.ddanzi.global.common.exception.ErrorResponse; +import co.orange.ddanzi.global.common.error.Error; +import co.orange.ddanzi.global.common.error.ErrorResponse; import jakarta.servlet.http.HttpServletRequest; import lombok.RequiredArgsConstructor; import lombok.extern.slf4j.Slf4j; diff --git a/src/main/java/co/orange/ddanzi/global/config/jwt/AuthUtils.java b/src/main/java/co/orange/ddanzi/global/config/jwt/AuthUtils.java new file mode 100644 index 00000000..665c7100 --- /dev/null +++ b/src/main/java/co/orange/ddanzi/global/config/jwt/AuthUtils.java @@ -0,0 +1,52 @@ +package co.orange.ddanzi.global.config.jwt; + +import co.orange.ddanzi.domain.user.User; +import co.orange.ddanzi.global.common.exception.UserNotFoundException; +import co.orange.ddanzi.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.stereotype.Component; + + +@Slf4j +@RequiredArgsConstructor +@Component +public class AuthUtils { + private final UserRepository userRepository; + + public User getUser() { + String currentUserNickname = getCurrentUserNickname(); + if (currentUserNickname == null) { + return null; + } + return userRepository.findByLoginId(currentUserNickname) + .orElseThrow(() -> new UserNotFoundException()); + + } + + public Authentication getAuthentication() { + // SecurityContext에서 인증 정보 가져오기 + Authentication authentication = SecurityContextHolder.getContext().getAuthentication(); + return authentication; + } + + public Object getPrincipal() { + // 현재 사용자의 principal 가져오기 + return getAuthentication().getPrincipal(); + + } + + public String getCurrentUserNickname() { + Object principalObject = getPrincipal(); + + if (principalObject instanceof UserDetails) { + UserDetails userDetails = (UserDetails) principalObject; + log.info("id token -> {}", userDetails.getUsername()); + return userDetails.getUsername(); + } + return null; + } +} diff --git a/src/main/java/co/orange/ddanzi/global/config/jwt/JwtFilter.java b/src/main/java/co/orange/ddanzi/global/config/jwt/JwtFilter.java new file mode 100644 index 00000000..e8110dd5 --- /dev/null +++ b/src/main/java/co/orange/ddanzi/global/config/jwt/JwtFilter.java @@ -0,0 +1,46 @@ +package co.orange.ddanzi.global.config.jwt; + +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; + +@Slf4j +@RequiredArgsConstructor +@Component +public class JwtFilter extends OncePerRequestFilter { + private final JwtUtils jwtUtils; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + + String token = jwtUtils.resolveJWT(request); + log.info("Request to {}: token={}", request.getRequestURI(), token); + + if (token != null && jwtUtils.validateToken(token)) { + Authentication authentication = jwtUtils.getAuthentication(token); + SecurityContextHolder.getContext().setAuthentication(authentication); + } + else { + log.info("No valid token found, proceeding without authentication"); + } + + filterChain.doFilter(request, response); + } + + @Override + protected boolean shouldNotFilter(HttpServletRequest request) throws ServletException { + String path = request.getRequestURI(); + return path.startsWith("/api/v1/auth") + || path.equals("/api/v1/search") + ; + } +} diff --git a/src/main/java/co/orange/ddanzi/global/config/jwt/JwtUtils.java b/src/main/java/co/orange/ddanzi/global/config/jwt/JwtUtils.java new file mode 100644 index 00000000..224b8248 --- /dev/null +++ b/src/main/java/co/orange/ddanzi/global/config/jwt/JwtUtils.java @@ -0,0 +1,114 @@ +package co.orange.ddanzi.global.config.jwt; + +import co.orange.ddanzi.global.common.error.Error; +import co.orange.ddanzi.global.common.exception.UnauthorizedException; +import io.jsonwebtoken.*; +import jakarta.servlet.http.HttpServletRequest; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.Authentication; +import org.springframework.security.core.userdetails.User; +import org.springframework.security.core.userdetails.UserDetails; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.data.redis.core.StringRedisTemplate; +import org.springframework.stereotype.Component; +import org.springframework.util.ObjectUtils; +import org.springframework.util.StringUtils; + +import java.util.Collections; +import java.util.Date; + + +@Slf4j +@RequiredArgsConstructor +@Component +public class JwtUtils { + + @Value("${secret.time.access}") + private long accessTokenTime; + + @Value("${secret.time.refresh}") + private long refreshTokenTime; + + @Value("${secret.key}") + private String jwtSecretKey; + + private final StringRedisTemplate stringRedisTemplate; + + public String createAccessToken(String idToken) { + Claims claims = Jwts.claims(); + claims.put("idToken", idToken); + + long validTime = accessTokenTime; + Date now = new Date(); + + return Jwts.builder() + .setClaims(claims) + .setIssuedAt(now) + .setExpiration(new Date(now.getTime() + validTime)) + .signWith(SignatureAlgorithm.HS256, jwtSecretKey) + .compact(); + } + + + + public String resolveJWT(HttpServletRequest request) { + String bearerToken = request.getHeader("Authorization"); + if (StringUtils.hasText(bearerToken) && bearerToken.startsWith("Bearer ")) { + return bearerToken.substring(7); + } else { + return null; + } + } + + public Authentication getAuthentication(String token) { + // 토큰 복호화 + Claims claims = getClaims(token); + if (claims.get("idToken") == null) { + throw new UnauthorizedException(Error.INVALID_JWT_EXCEPTION); + } + + // UserDetails 객체를 생성하여 Authentication 반환 + UserDetails principal = new User(getIdTokenFromToken(token), "", Collections.emptyList()); + return new UsernamePasswordAuthenticationToken(principal, "", Collections.emptyList()); + } + + + + public boolean validateToken(String token) { + if (!StringUtils.hasText(token)) { + throw new UnauthorizedException(Error.JWT_TOKEN_NOT_EXISTS); + } +// if(isLogout(token)){ +// throw new UnauthorizedException(Error.LOG_OUT_JWT_TOKEN); +// } + try { + Claims claims = Jwts.parser().setSigningKey(jwtSecretKey).parseClaimsJws(token).getBody(); + log.info("token \"id token\" : " + claims.get("idToken")); + return true; + } catch (MalformedJwtException e) { + throw new UnauthorizedException(Error.INVALID_JWT_EXCEPTION); + } catch (ExpiredJwtException e) { + throw new UnauthorizedException(Error.JWT_EXPIRED); + } catch (UnauthorizedException e) { + return false; + } + } + + public String getIdTokenFromToken(String token) { + return getClaims(token).get("idToken").toString(); + } + + + public Claims getClaims(String token) { + return Jwts.parser().setSigningKey(jwtSecretKey).parseClaimsJws(token).getBody(); + } + + public boolean isLogout(String accessToken) { + return !ObjectUtils.isEmpty(stringRedisTemplate.opsForValue().get(accessToken)); + } + + + +} diff --git a/src/main/java/co/orange/ddanzi/global/config/security/SecurityConfig.java b/src/main/java/co/orange/ddanzi/global/config/security/SecurityConfig.java new file mode 100644 index 00000000..5061cf56 --- /dev/null +++ b/src/main/java/co/orange/ddanzi/global/config/security/SecurityConfig.java @@ -0,0 +1,43 @@ +package co.orange.ddanzi.global.config.security; + +import co.orange.ddanzi.global.config.jwt.JwtFilter; +import co.orange.ddanzi.global.config.jwt.JwtUtils; +import lombok.RequiredArgsConstructor; +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; +import org.springframework.security.web.SecurityFilterChain; +import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter; + +@Configuration +@RequiredArgsConstructor +@EnableWebSecurity +public class SecurityConfig { + + private final JwtUtils jwtUtils; + + private String[] permitList = { + "/api/v1/auth/**", + "/api/v1/auth/signin/test", + "/api/v1/home/**", + "/api/v1/search/**" + }; + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .httpBasic(AbstractHttpConfigurer::disable) + .csrf(AbstractHttpConfigurer::disable) + .formLogin(AbstractHttpConfigurer::disable) + .sessionManagement(AbstractHttpConfigurer::disable) + .authorizeHttpRequests((authorizeRequests) -> + authorizeRequests + .requestMatchers(permitList).permitAll() + .anyRequest().authenticated() + ) + .addFilterBefore(new JwtFilter(jwtUtils), UsernamePasswordAuthenticationFilter.class); + return http.build(); + } +} diff --git a/src/main/java/co/orange/ddanzi/repository/InterestProductRepository.java b/src/main/java/co/orange/ddanzi/repository/InterestProductRepository.java index a72cf80f..f8ab4fd0 100644 --- a/src/main/java/co/orange/ddanzi/repository/InterestProductRepository.java +++ b/src/main/java/co/orange/ddanzi/repository/InterestProductRepository.java @@ -13,6 +13,8 @@ public interface InterestProductRepository extends JpaRepository { + boolean existsByIdUserAndIdProduct(User user, Product product); + @Query("SELECT CASE WHEN COUNT(ip) > 1000 THEN 999 ELSE COUNT(ip) END FROM InterestProduct ip " + "WHERE ip.id.product.id = :productId") Integer countByProductIdWithLimit(@Param("productId") String productId); diff --git a/src/main/java/co/orange/ddanzi/repository/UserRepository.java b/src/main/java/co/orange/ddanzi/repository/UserRepository.java index c343075c..a9e4861e 100644 --- a/src/main/java/co/orange/ddanzi/repository/UserRepository.java +++ b/src/main/java/co/orange/ddanzi/repository/UserRepository.java @@ -3,5 +3,8 @@ import co.orange.ddanzi.domain.user.User; import org.springframework.data.repository.CrudRepository; +import java.util.Optional; + public interface UserRepository extends CrudRepository { + Optional findByLoginId(String loginId); } diff --git a/src/main/java/co/orange/ddanzi/service/AuthService.java b/src/main/java/co/orange/ddanzi/service/AuthService.java new file mode 100644 index 00000000..3c3da45d --- /dev/null +++ b/src/main/java/co/orange/ddanzi/service/AuthService.java @@ -0,0 +1,42 @@ +package co.orange.ddanzi.service; + +import co.orange.ddanzi.domain.user.User; +import co.orange.ddanzi.dto.auth.AuthResponseDto; +import co.orange.ddanzi.global.common.error.Error; +import co.orange.ddanzi.global.common.response.ApiResponse; +import co.orange.ddanzi.global.common.response.Success; +import co.orange.ddanzi.global.config.jwt.JwtUtils; +import co.orange.ddanzi.repository.UserRepository; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.stereotype.Service; + +import java.util.Optional; + + +@Slf4j +@RequiredArgsConstructor +@Service +public class AuthService { + private final UserRepository userRepository; + private final JwtUtils jwtUtils; + + @Transactional + public ApiResponse testSignin(String idToken){ + + Optional optionalUser = userRepository.findByLoginId(idToken); + if(optionalUser.isEmpty()){ + return ApiResponse.onFailure(Error.ERROR, null); + } + User user = optionalUser.get(); + + AuthResponseDto responseDto = AuthResponseDto.builder() + .accesstoken(jwtUtils.createAccessToken(user.getLoginId())) + .nickname(user.getNickname()) + .build(); + return ApiResponse.onSuccess(Success.SUCCESS, responseDto); + } +} + + diff --git a/src/main/java/co/orange/ddanzi/service/HomeService.java b/src/main/java/co/orange/ddanzi/service/HomeService.java index 112b0908..d813a069 100644 --- a/src/main/java/co/orange/ddanzi/service/HomeService.java +++ b/src/main/java/co/orange/ddanzi/service/HomeService.java @@ -2,11 +2,13 @@ import co.orange.ddanzi.domain.Banner; import co.orange.ddanzi.domain.product.*; +import co.orange.ddanzi.domain.user.User; import co.orange.ddanzi.dto.ProductInfo; import co.orange.ddanzi.dto.home.*; -import co.orange.ddanzi.global.common.exception.Error; +import co.orange.ddanzi.global.common.error.Error; import co.orange.ddanzi.global.common.response.ApiResponse; import co.orange.ddanzi.global.common.response.Success; +import co.orange.ddanzi.global.config.jwt.AuthUtils; import co.orange.ddanzi.global.redis.RedisRepository; import co.orange.ddanzi.repository.*; import jakarta.transaction.Transactional; @@ -22,6 +24,7 @@ @RequiredArgsConstructor @Service public class HomeService { + private final AuthUtils authUtils; private final ProductRepository productRepository; private final BannerRepository bannerRepository; private final DiscountRepository discountRepository; @@ -32,10 +35,11 @@ public class HomeService { @Transactional public ApiResponse getProductList(){ + User user = authUtils.getUser(); Banner banner = bannerRepository.findByIsSelected(Boolean.TRUE); List productList = productRepository.findAllByStock(0); - List productInfoList = setProductList(productList, interestProductRepository); + List productInfoList = setProductList(user, productList, interestProductRepository); HomeResponseDto responseDto = HomeResponseDto.builder() .homeImgUrl(banner.getImgUrl()) .productList(productInfoList).build(); @@ -94,7 +98,7 @@ public ApiResponse getProductDetail(String devicetoken, String productId){ return ApiResponse.onSuccess(Success.GET_PRODUCT_DETAIL_SUCCESS,responseDto); } - public List setProductList(List productList, InterestProductRepository interestProductRepository){ + public List setProductList(User user, List productList, InterestProductRepository interestProductRepository){ List productInfoList = new ArrayList<>(); for(Product product : productList){ Discount discount = discountRepository.findById(product.getId()).orElse(null); @@ -106,6 +110,7 @@ public List setProductList(List productList, InterestProdu .salePrice(product.getOriginPrice() - discount.getDiscountPrice()) .imgUrl(product.getImgUrl()) .interestCount(interestProductRepository.countByProductIdWithLimit(product.getId())) + .isInterested(interestProductRepository.existsByIdUserAndIdProduct(user, product)) .build()); } return productInfoList; diff --git a/src/main/java/co/orange/ddanzi/service/InterestService.java b/src/main/java/co/orange/ddanzi/service/InterestService.java index 396d9cca..814b507b 100644 --- a/src/main/java/co/orange/ddanzi/service/InterestService.java +++ b/src/main/java/co/orange/ddanzi/service/InterestService.java @@ -3,11 +3,11 @@ import co.orange.ddanzi.domain.product.Product; import co.orange.ddanzi.domain.user.InterestProduct; import co.orange.ddanzi.domain.user.User; -import co.orange.ddanzi.domain.user.pk.InterestProductId; import co.orange.ddanzi.dto.interest.InterestResponseDto; -import co.orange.ddanzi.global.common.exception.Error; +import co.orange.ddanzi.global.common.error.Error; import co.orange.ddanzi.global.common.response.ApiResponse; import co.orange.ddanzi.global.common.response.Success; +import co.orange.ddanzi.global.config.jwt.AuthUtils; import co.orange.ddanzi.repository.InterestProductRepository; import co.orange.ddanzi.repository.ProductRepository; import co.orange.ddanzi.repository.UserRepository; @@ -20,14 +20,13 @@ @RequiredArgsConstructor @Service public class InterestService { - private final UserRepository userRepository; + private final AuthUtils authUtils; private final ProductRepository productRepository; private final InterestProductRepository interestProductRepository; @Transactional public ApiResponse addInterest(String productId) { - log.info("사용자 조회", productId); - User user = userRepository.findById(1L).orElse(null); + User user = authUtils.getUser(); log.info("상품 조회 -> product_id: {}", productId); Product product = productRepository.findById(productId).orElse(null); @@ -49,8 +48,7 @@ public ApiResponse addInterest(String productId) { @Transactional public ApiResponse deleteInterest(String productId) { - log.info("사용자 조회", productId); - User user = userRepository.findById(1L).orElse(null); + User user = authUtils.getUser(); log.info("상품 조회 -> product_id: {}", productId); Product product = productRepository.findById(productId).orElse(null); diff --git a/src/main/java/co/orange/ddanzi/service/ItemService.java b/src/main/java/co/orange/ddanzi/service/ItemService.java index 1fc8d318..41ee49f9 100644 --- a/src/main/java/co/orange/ddanzi/service/ItemService.java +++ b/src/main/java/co/orange/ddanzi/service/ItemService.java @@ -5,7 +5,7 @@ import co.orange.ddanzi.domain.user.User; import co.orange.ddanzi.dto.item.SaveItemRequestDto; import co.orange.ddanzi.dto.item.SaveItemResponseDto; -import co.orange.ddanzi.global.common.exception.Error; +import co.orange.ddanzi.global.common.error.Error; import co.orange.ddanzi.global.common.response.ApiResponse; import co.orange.ddanzi.global.common.response.Success; import co.orange.ddanzi.repository.*; diff --git a/src/main/java/co/orange/ddanzi/service/MyPageService.java b/src/main/java/co/orange/ddanzi/service/MyPageService.java index f88fb042..a515b362 100644 --- a/src/main/java/co/orange/ddanzi/service/MyPageService.java +++ b/src/main/java/co/orange/ddanzi/service/MyPageService.java @@ -6,6 +6,7 @@ import co.orange.ddanzi.dto.mypage.MyPageInterestResponseDto; import co.orange.ddanzi.global.common.response.ApiResponse; import co.orange.ddanzi.global.common.response.Success; +import co.orange.ddanzi.global.config.jwt.AuthUtils; import co.orange.ddanzi.repository.InterestProductRepository; import co.orange.ddanzi.repository.ProductRepository; import co.orange.ddanzi.repository.UserRepository; @@ -22,14 +23,13 @@ @RequiredArgsConstructor @Service public class MyPageService { + private final AuthUtils authUtils; private final HomeService homeService; - private final UserRepository userRepository; private final InterestProductRepository interestProductRepository; - private final ProductRepository productRepository; @Transactional public ApiResponse getMyPage(){ - User user = userRepository.findById(1L).orElse(null); + User user = authUtils.getUser(); String nickname = user.getNickname(); Map response = new HashMap<>(); response.put("nickname", nickname); @@ -38,11 +38,11 @@ public ApiResponse getMyPage(){ @Transactional public ApiResponse getInterest(){ - User user = userRepository.findById(1L).orElse(null); + User user = authUtils.getUser(); log.info("찜한 상품 찾기"); List productList = interestProductRepository.findProductsByUserId(user.getId()); log.info("찜한 상품의 정보 입력하기"); - List productInfoList = homeService.setProductList(productList,interestProductRepository); + List productInfoList = homeService.setProductList(user, productList,interestProductRepository); MyPageInterestResponseDto responseDto = MyPageInterestResponseDto.builder() .totalCount(productList.size()) .productList(productInfoList) diff --git a/src/main/java/co/orange/ddanzi/service/ProductService.java b/src/main/java/co/orange/ddanzi/service/ProductService.java index 9421e20c..a8f65583 100644 --- a/src/main/java/co/orange/ddanzi/service/ProductService.java +++ b/src/main/java/co/orange/ddanzi/service/ProductService.java @@ -9,7 +9,7 @@ import co.orange.ddanzi.dto.item.ConfirmProductRequestDto; import co.orange.ddanzi.dto.item.ConfirmProductResponseDto; import co.orange.ddanzi.dto.order.CheckProductResponseDto; -import co.orange.ddanzi.global.common.exception.Error; +import co.orange.ddanzi.global.common.error.Error; import co.orange.ddanzi.global.common.response.ApiResponse; import co.orange.ddanzi.global.common.response.Success; import co.orange.ddanzi.repository.*; diff --git a/src/main/java/co/orange/ddanzi/service/SearchService.java b/src/main/java/co/orange/ddanzi/service/SearchService.java index a81b68d8..f57080f9 100644 --- a/src/main/java/co/orange/ddanzi/service/SearchService.java +++ b/src/main/java/co/orange/ddanzi/service/SearchService.java @@ -1,11 +1,13 @@ package co.orange.ddanzi.service; import co.orange.ddanzi.domain.product.Product; +import co.orange.ddanzi.domain.user.User; import co.orange.ddanzi.dto.ProductInfo; import co.orange.ddanzi.dto.search.SearchPageResponseDto; import co.orange.ddanzi.dto.search.SearchResultResponseDto; import co.orange.ddanzi.global.common.response.ApiResponse; import co.orange.ddanzi.global.common.response.Success; +import co.orange.ddanzi.global.config.jwt.AuthUtils; import co.orange.ddanzi.global.redis.RedisRepository; import co.orange.ddanzi.repository.InterestProductRepository; import co.orange.ddanzi.repository.ProductRepository; @@ -21,6 +23,7 @@ @RequiredArgsConstructor @Service public class SearchService { + private final AuthUtils authUtils; private final HomeService homeService; private final ProductRepository productRepository; private final InterestProductRepository interestProductRepository; @@ -28,11 +31,12 @@ public class SearchService { @Transactional public ApiResponse searchPage(String devicetoken) { + User user = authUtils.getUser(); List topSearchedList = List.of("예시1", "예시2", "예시3"); log.info("Searching page for devicetoken: {}", devicetoken); Set recentViewedProductIds = redisRepository.getRecentProducts(devicetoken); List productList = productRepository.findByIdIn(recentViewedProductIds); - List productInfoList = homeService.setProductList(productList, interestProductRepository); + List productInfoList = homeService.setProductList(user, productList, interestProductRepository); return ApiResponse.onSuccess(Success.GET_SEARCH_SCREEN_SUCCESS, SearchPageResponseDto.builder() .topSearchedList(topSearchedList) .recentlyViewedList(productInfoList) @@ -41,10 +45,11 @@ public ApiResponse searchPage(String devicetoken) { @Transactional public ApiResponse searchKeyword(String keyword) { + User user = authUtils.getUser(); List topSearchedList = List.of("예시1", "예시2", "예시3"); log.info("Search for keyword: {}", keyword); List productList = productRepository.findAllByName(keyword); - List productInfoList = homeService.setProductList(productList, interestProductRepository); + List productInfoList = homeService.setProductList(user, productList, interestProductRepository); return ApiResponse.onSuccess(Success.GET_SEARCH_RESULTS_SUCCESS, SearchResultResponseDto.builder() .topSearchedList(topSearchedList) .searchedProductList(productInfoList) diff --git a/src/main/java/co/orange/ddanzi/service/SettingService.java b/src/main/java/co/orange/ddanzi/service/SettingService.java index 145e0fe2..382cf2ea 100644 --- a/src/main/java/co/orange/ddanzi/service/SettingService.java +++ b/src/main/java/co/orange/ddanzi/service/SettingService.java @@ -2,9 +2,10 @@ import co.orange.ddanzi.domain.user.*; import co.orange.ddanzi.dto.setting.*; -import co.orange.ddanzi.global.common.exception.Error; +import co.orange.ddanzi.global.common.error.Error; import co.orange.ddanzi.global.common.response.ApiResponse; import co.orange.ddanzi.global.common.response.Success; +import co.orange.ddanzi.global.config.jwt.AuthUtils; import co.orange.ddanzi.repository.AccountRepository; import co.orange.ddanzi.repository.AddressRepository; import co.orange.ddanzi.repository.PushAlarmRepository; @@ -18,14 +19,15 @@ @RequiredArgsConstructor @Service public class SettingService { - private final UserRepository userRepository; + private final AuthUtils authUtils; private final AddressRepository addressRepository; private final AccountRepository accountRepository; private final PushAlarmRepository pushAlarmRepository; + @Transactional public ApiResponse getSetting(){ - User user = userRepository.findById(1L).orElse(null); + User user = authUtils.getUser(); Authentication authentication = user.getAuthentication(); String name = null; String phone = null; if(authentication != null){ @@ -42,32 +44,43 @@ public ApiResponse getSetting(){ return ApiResponse.onSuccess(Success.GET_SETTING_SCREEN_SUCCESS, responseDto); } + + + @Transactional + public ApiResponse enterAddress(){ + User user = authUtils.getUser(); + return ApiResponse.onSuccess(Success.GET_SETTING_ADDRESS_SUCCESS, EnterAddressResponseDto.builder() + .name(user.getAuthentication().getName()) + .phone(user.getAuthentication().getPhone()) + .build()); + } + @Transactional public ApiResponse getAddress(){ - User user = userRepository.findById(1L).orElse(null); + User user = authUtils.getUser(); Address address = addressRepository.findByUser(user); - AddressResponseDto responseDto = setAddressDto(address, user.getAuthentication()); + AddressResponseDto responseDto = setAddressDto(address); return ApiResponse.onSuccess(Success.GET_SETTING_ADDRESS_SUCCESS, responseDto); } @Transactional public ApiResponse addAddress(AddressRequestDto requestDto){ - User user = userRepository.findById(1L).orElse(null); + User user = authUtils.getUser(); Address newAddress = requestDto.toEntity(user); newAddress = addressRepository.save(newAddress); - AddressResponseDto responseDto = setAddressDto(newAddress, user.getAuthentication()); + AddressResponseDto responseDto = setAddressDto(newAddress); return ApiResponse.onSuccess(Success.CREATE_ADDRESS_SUCCESS, responseDto); } @Transactional public ApiResponse updateAddress(Long addressId, AddressRequestDto requestDto){ - User user = userRepository.findById(1L).orElse(null); + User user = authUtils.getUser(); Address updatedAddress = addressRepository.findById(addressId).orElse(null); if(updatedAddress == null){ return ApiResponse.onFailure(Error.ADDRESS_NOT_FOUND, null); } updatedAddress.update(requestDto); - AddressResponseDto responseDto = setAddressDto(updatedAddress, user.getAuthentication()); + AddressResponseDto responseDto = setAddressDto(updatedAddress); return ApiResponse.onSuccess(Success.PUT_ADDRESS_SUCCESS, responseDto); } @@ -78,12 +91,12 @@ public ApiResponse deleteAddress(Long addressId){ return ApiResponse.onFailure(Error.ADDRESS_NOT_FOUND, null); } addressRepository.delete(deletedAddress); - return ApiResponse.onSuccess(Success.DELETE_ADDRESS_SUCCESS, null); + return ApiResponse.onSuccess(Success.DELETE_ADDRESS_SUCCESS, true); } @Transactional public ApiResponse getAccount(){ - User user = userRepository.findById(1L).orElse(null); + User user = authUtils.getUser(); Account account = accountRepository.findByUserId(user); AccountResponseDto responseDto = setAccountDto(account, user.getAuthentication()); return ApiResponse.onSuccess(Success.GET_SETTING_ACCOUNT_SUCCESS, responseDto); @@ -91,7 +104,7 @@ public ApiResponse getAccount(){ @Transactional public ApiResponse addAccount(AccountRequestDto requestDto){ - User user = userRepository.findById(1L).orElse(null); + User user = authUtils.getUser(); Authentication authentication = user.getAuthentication(); log.info("본인인증 여부 확인"); @@ -117,7 +130,7 @@ public ApiResponse addAccount(AccountRequestDto requestDto){ @Transactional public ApiResponse updateAccount(Long accountId, AccountRequestDto requestDto){ - User user = userRepository.findById(1L).orElse(null); + User user = authUtils.getUser(); Account updatedAccount = accountRepository.findById(accountId).orElse(null); if(updatedAccount == null){ return ApiResponse.onFailure(Error.ACCOUNT_NOT_FOUND, null); @@ -139,7 +152,7 @@ public ApiResponse deleteAccount(Long accountId){ @Transactional public ApiResponse updatePushAlarm(PushAlarmRequestDto requestDto){ - User user = userRepository.findById(1L).orElse(null); + User user = authUtils.getUser(); PushAlarm pushAlarm = pushAlarmRepository.findByUser(user); if(pushAlarm == null){ return ApiResponse.onFailure(Error.PUSH_ALARM_NOT_FOUND, null); @@ -147,15 +160,15 @@ public ApiResponse updatePushAlarm(PushAlarmRequestDto requestDto){ pushAlarm.update(requestDto); return ApiResponse.onSuccess(Success.PUT_PUSH_ALARM_SUCCESS, null); } - private AddressResponseDto setAddressDto(Address address, Authentication authentication){ + private AddressResponseDto setAddressDto(Address address){ return AddressResponseDto.builder() .addressId(address != null ? address.getId() : null) - .name(authentication != null ? authentication.getName() : null) + .recipient(address != null ? address.getRecipient() : null) .zipCode(address != null ? address.getZipCode() : null) .type(address != null ? address.getType() : null) .address(address != null ? address.getAddress() : null) .detailAddress(address != null ? address.getDetailAddress() : null) - .phone(authentication != null ? authentication.getPhone() : null) + .recipientPhone(address != null ? address.getRecipientPhone() : null) .build(); } diff --git a/src/main/resources/application.yml b/src/main/resources/application.yml index cacc530a..eb86b49f 100644 --- a/src/main/resources/application.yml +++ b/src/main/resources/application.yml @@ -1,4 +1,4 @@ spring: profiles: - active: db + active: db, product