From 70fb5907caf5189f14d5b6e93d049809c16596a7 Mon Sep 17 00:00:00 2001 From: LeeDongjae Date: Tue, 8 Oct 2024 18:31:44 +0900 Subject: [PATCH 01/24] =?UTF-8?q?Chore:=20build.gradle,=20application.yml?= =?UTF-8?q?=20=EC=84=A4=EC=A0=95=20=EC=B6=94=EA=B0=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/build.gradle | 1 + backend/src/main/resources/application.yml | 13 +++++++++++++ 2 files changed, 14 insertions(+) diff --git a/backend/build.gradle b/backend/build.gradle index aa3ec58..de7c91e 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -27,6 +27,7 @@ dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' //implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-web' + implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index f95d286..77f41c2 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -16,10 +16,23 @@ spring: max-request-size: 15MB config: additional-location: classpath:application-secret.yml + security: + oauth2: + client: + registration: + google: + client-id: ${GOOGLE.CLIENT-ID} + client-secret: ${GOOGLE.CLIENT-SECRET} + redirect-uri: ${GOOGLE.REDIRECT-URI} + scope: + - email + - profile + logging: level: org.hibernate.SQL: DEBUG org.hibernate.type: TRACE + server: servlet: encoding: From 45c39545401bda01193dabdbdb44de7c8a8f35cc Mon Sep 17 00:00:00 2001 From: milk-stone Date: Wed, 9 Oct 2024 21:50:14 +0900 Subject: [PATCH 02/24] =?UTF-8?q?feat=20:=20User=20=EC=97=94=ED=8B=B0?= =?UTF-8?q?=ED=8B=B0=20=ED=95=84=EB=93=9C=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../backend/domain/user/entity/User.java | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 backend/src/main/java/com/itec0401/backend/domain/user/entity/User.java diff --git a/backend/src/main/java/com/itec0401/backend/domain/user/entity/User.java b/backend/src/main/java/com/itec0401/backend/domain/user/entity/User.java new file mode 100644 index 0000000..cd1dd47 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/user/entity/User.java @@ -0,0 +1,30 @@ +package com.itec0401.backend.domain.user.entity; + +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor +public class User { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "user_id") + private Long id; + + private String name; + + private String nickname; + + // google login API 보고 email, password 필드 생각 다시 해야함 + + // 유저 추가 정보 + private int gender; + private int age; + private double height; + private double weight; + private String tone; + + // mapping + +} From 25e25b31b970850a55cabec7b54e7319e68cd653 Mon Sep 17 00:00:00 2001 From: LeeDongjae Date: Thu, 10 Oct 2024 13:46:48 +0900 Subject: [PATCH 03/24] =?UTF-8?q?Feat:=20"=EC=9D=B8=EA=B0=80=EC=BD=94?= =?UTF-8?q?=EB=93=9C=20=EB=B0=9C=EA=B8=89=20=EA=B8=B0=EB=8A=A5=20=EA=B5=AC?= =?UTF-8?q?=ED=98=84"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Redirect URI로 인가코드 받아오기 기능 구현 --- .../login/controller/LoginController.java | 17 +++++++++++++++++ .../backend/login/service/LoginService.java | 5 +++++ .../backend/login/service/LoginServiceImpl.java | 12 ++++++++++++ backend/src/main/resources/application.yml | 2 +- 4 files changed, 35 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/java/com/itec0401/backend/login/controller/LoginController.java create mode 100644 backend/src/main/java/com/itec0401/backend/login/service/LoginService.java create mode 100644 backend/src/main/java/com/itec0401/backend/login/service/LoginServiceImpl.java diff --git a/backend/src/main/java/com/itec0401/backend/login/controller/LoginController.java b/backend/src/main/java/com/itec0401/backend/login/controller/LoginController.java new file mode 100644 index 0000000..4bc37bf --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/login/controller/LoginController.java @@ -0,0 +1,17 @@ +package com.itec0401.backend.login.controller; + +import com.itec0401.backend.login.service.LoginService; +import lombok.RequiredArgsConstructor; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping(value = "/login/oauth2", produces = "application/json") +@RequiredArgsConstructor +public class LoginController { + private final LoginService loginService; + + @GetMapping("/code/{registrationId}") + public void oauthLogin(@RequestParam String code, @PathVariable String registrationId) { + loginService.oauthLogin(code, registrationId); + } +} diff --git a/backend/src/main/java/com/itec0401/backend/login/service/LoginService.java b/backend/src/main/java/com/itec0401/backend/login/service/LoginService.java new file mode 100644 index 0000000..611f5ce --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/login/service/LoginService.java @@ -0,0 +1,5 @@ +package com.itec0401.backend.login.service; + +public interface LoginService { + void oauthLogin(String code, String registrationId); +} diff --git a/backend/src/main/java/com/itec0401/backend/login/service/LoginServiceImpl.java b/backend/src/main/java/com/itec0401/backend/login/service/LoginServiceImpl.java new file mode 100644 index 0000000..abe9899 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/login/service/LoginServiceImpl.java @@ -0,0 +1,12 @@ +package com.itec0401.backend.login.service; + +import org.springframework.stereotype.Service; + +@Service +public class LoginServiceImpl implements LoginService{ + @Override + public void oauthLogin(String code, String registrationId) { + System.out.println("code = " + code); + System.out.println("registrationId = " + registrationId); + } +} diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index 77f41c2..c77f09b 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -8,7 +8,7 @@ spring: hibernate: ddl-auto: create show-sql: true - database-platform: org.hibernate.dialect.MySQL8Dialect + database-platform: org.hibernate.dialect.MySQLDialect servlet: multipart: enabled: true From f755cdf4aeed7a368b17184448a4690c52092bc6 Mon Sep 17 00:00:00 2001 From: milk-stone Date: Thu, 10 Oct 2024 23:28:15 +0900 Subject: [PATCH 04/24] =?UTF-8?q?feat=20:=20JPA=20Auditing=20=EC=84=A4?= =?UTF-8?q?=EC=A0=95?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit createdAt, updatedAt 을 기록하기 위한 JPA Auditing 기능 설정 --- .../itec0401/backend/BackendApplication.java | 2 ++ .../itec0401/backend/global/BaseEntity.java | 18 +++++++++++++++ .../global/BaseEntityWithUpdatedAt.java | 22 +++++++++++++++++++ 3 files changed, 42 insertions(+) create mode 100644 backend/src/main/java/com/itec0401/backend/global/BaseEntity.java create mode 100644 backend/src/main/java/com/itec0401/backend/global/BaseEntityWithUpdatedAt.java diff --git a/backend/src/main/java/com/itec0401/backend/BackendApplication.java b/backend/src/main/java/com/itec0401/backend/BackendApplication.java index 2a24804..69bb119 100644 --- a/backend/src/main/java/com/itec0401/backend/BackendApplication.java +++ b/backend/src/main/java/com/itec0401/backend/BackendApplication.java @@ -2,8 +2,10 @@ import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; +import org.springframework.data.jpa.repository.config.EnableJpaAuditing; @SpringBootApplication +@EnableJpaAuditing public class BackendApplication { public static void main(String[] args) { diff --git a/backend/src/main/java/com/itec0401/backend/global/BaseEntity.java b/backend/src/main/java/com/itec0401/backend/global/BaseEntity.java new file mode 100644 index 0000000..7b324d0 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/global/BaseEntity.java @@ -0,0 +1,18 @@ +package com.itec0401.backend.global; + +import jakarta.persistence.EntityListeners; +import jakarta.persistence.MappedSuperclass; +import lombok.Getter; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import java.time.LocalDateTime; + + +@MappedSuperclass +@Getter +@EntityListeners(AuditingEntityListener.class) +public class BaseEntity { + @CreatedDate + private LocalDateTime createdAt; +} diff --git a/backend/src/main/java/com/itec0401/backend/global/BaseEntityWithUpdatedAt.java b/backend/src/main/java/com/itec0401/backend/global/BaseEntityWithUpdatedAt.java new file mode 100644 index 0000000..d35a457 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/global/BaseEntityWithUpdatedAt.java @@ -0,0 +1,22 @@ +package com.itec0401.backend.global; + + +import jakarta.persistence.EntityListeners; +import jakarta.persistence.MappedSuperclass; +import lombok.Getter; +import org.springframework.data.annotation.CreatedDate; +import org.springframework.data.annotation.LastModifiedDate; +import org.springframework.data.jpa.domain.support.AuditingEntityListener; + +import java.time.LocalDateTime; + +@MappedSuperclass +@Getter +@EntityListeners(AuditingEntityListener.class) +public class BaseEntityWithUpdatedAt { + @CreatedDate + private LocalDateTime createdAt; + + @LastModifiedDate + private LocalDateTime updatedAt; +} From 729f191ef03f7f0b177464f62dd04b1c71fe8319 Mon Sep 17 00:00:00 2001 From: milk-stone Date: Fri, 11 Oct 2024 01:50:38 +0900 Subject: [PATCH 05/24] =?UTF-8?q?feat=20:=20Entity=20=EC=9E=91=EC=84=B1?= =?UTF-8?q?=EC=A4=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Color, UserColor, Style, UserStyle, User, Coordination Entity 작성 완료. Clothing, CoordinationClothing Entity 및 연관관계 작성해야함 --- .../backend/domain/color/entity/Color.java | 23 ++++++++++++++++ .../coordination/entity/Coordination.java | 24 +++++++++++++++++ .../backend/domain/style/entity/Style.java | 22 ++++++++++++++++ .../backend/domain/user/entity/User.java | 19 +++++++++++++- .../domain/usercolor/entity/UserColor.java | 26 +++++++++++++++++++ .../domain/userstyle/entity/UserStyle.java | 25 ++++++++++++++++++ 6 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 backend/src/main/java/com/itec0401/backend/domain/color/entity/Color.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/coordination/entity/Coordination.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/style/entity/Style.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/usercolor/entity/UserColor.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/userstyle/entity/UserStyle.java diff --git a/backend/src/main/java/com/itec0401/backend/domain/color/entity/Color.java b/backend/src/main/java/com/itec0401/backend/domain/color/entity/Color.java new file mode 100644 index 0000000..782867d --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/color/entity/Color.java @@ -0,0 +1,23 @@ +package com.itec0401.backend.domain.color.entity; + +import com.itec0401.backend.domain.usercolor.entity.UserColor; +import com.itec0401.backend.global.BaseEntity; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Entity +@Getter +@NoArgsConstructor +public class Color extends BaseEntity { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "color_id") + private Long id; + + private String style; + + @OneToMany(mappedBy = "color") + private List userColors; +} diff --git a/backend/src/main/java/com/itec0401/backend/domain/coordination/entity/Coordination.java b/backend/src/main/java/com/itec0401/backend/domain/coordination/entity/Coordination.java new file mode 100644 index 0000000..212341c --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/coordination/entity/Coordination.java @@ -0,0 +1,24 @@ +package com.itec0401.backend.domain.coordination.entity; + +import com.itec0401.backend.domain.user.entity.User; +import com.itec0401.backend.global.BaseEntity; +import jakarta.persistence.*; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor +public class Coordination extends BaseEntity { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "coordination_id") + private Long id; + + private Boolean liked; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "user_id", nullable = false) + private User user; + +} diff --git a/backend/src/main/java/com/itec0401/backend/domain/style/entity/Style.java b/backend/src/main/java/com/itec0401/backend/domain/style/entity/Style.java new file mode 100644 index 0000000..2b1c21b --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/style/entity/Style.java @@ -0,0 +1,22 @@ +package com.itec0401.backend.domain.style.entity; + +import com.itec0401.backend.domain.userstyle.entity.UserStyle; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Entity +@Getter +@NoArgsConstructor +public class Style { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "style_id") + private Long id; + + private String style; + + @OneToMany(mappedBy = "style") + private List userStyles; +} diff --git a/backend/src/main/java/com/itec0401/backend/domain/user/entity/User.java b/backend/src/main/java/com/itec0401/backend/domain/user/entity/User.java index cd1dd47..4132ecf 100644 --- a/backend/src/main/java/com/itec0401/backend/domain/user/entity/User.java +++ b/backend/src/main/java/com/itec0401/backend/domain/user/entity/User.java @@ -1,22 +1,31 @@ package com.itec0401.backend.domain.user.entity; +import com.itec0401.backend.domain.coordination.entity.Coordination; +import com.itec0401.backend.domain.usercolor.entity.UserColor; +import com.itec0401.backend.domain.userstyle.entity.UserStyle; +import com.itec0401.backend.global.BaseEntityWithUpdatedAt; import jakarta.persistence.*; import lombok.Getter; import lombok.NoArgsConstructor; +import java.util.List; + @Entity @Getter @NoArgsConstructor -public class User { +public class User extends BaseEntityWithUpdatedAt { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "user_id") private Long id; + @Column(nullable = false) private String name; + @Column(nullable = false) private String nickname; // google login API 보고 email, password 필드 생각 다시 해야함 + // google 로그인 하면 이메일, 닉네임 받아올 수 있으려나? // 유저 추가 정보 private int gender; @@ -27,4 +36,12 @@ public class User { // mapping + @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) + private List coordinationList; + + @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) + private List userStyleList; + + @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) + private List userColorList; } diff --git a/backend/src/main/java/com/itec0401/backend/domain/usercolor/entity/UserColor.java b/backend/src/main/java/com/itec0401/backend/domain/usercolor/entity/UserColor.java new file mode 100644 index 0000000..2632f64 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/usercolor/entity/UserColor.java @@ -0,0 +1,26 @@ +package com.itec0401.backend.domain.usercolor.entity; + +import com.itec0401.backend.domain.color.entity.Color; +import com.itec0401.backend.domain.user.entity.User; +import com.itec0401.backend.global.BaseEntityWithUpdatedAt; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor +public class UserColor extends BaseEntityWithUpdatedAt { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "usercolor_id") + private Long id; + + @ManyToOne + @JoinColumn(name = "user_id") + private User user; + + @ManyToOne + @JoinColumn(name = "color_id") + private Color color; + +} diff --git a/backend/src/main/java/com/itec0401/backend/domain/userstyle/entity/UserStyle.java b/backend/src/main/java/com/itec0401/backend/domain/userstyle/entity/UserStyle.java new file mode 100644 index 0000000..97b722d --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/userstyle/entity/UserStyle.java @@ -0,0 +1,25 @@ +package com.itec0401.backend.domain.userstyle.entity; + +import com.itec0401.backend.domain.style.entity.Style; +import com.itec0401.backend.domain.user.entity.User; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor +public class UserStyle { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "userstyle_id") + private Long id; + + @ManyToOne + @JoinColumn(name = "user_id") + private User user; + + @ManyToOne + @JoinColumn(name = "style_id") + private Style style; + +} From 40f11fe1d3d8c45b692e4a6f9392202e353ed5e3 Mon Sep 17 00:00:00 2001 From: milk-stone Date: Fri, 11 Oct 2024 17:46:00 +0900 Subject: [PATCH 06/24] =?UTF-8?q?feat=20:=20=EC=9E=94=EC=97=AC=20=EC=97=94?= =?UTF-8?q?=ED=8B=B0=ED=8B=B0=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Clothing, CoordinationClothing 엔티티 작성 연관관계 모두 매핑 완료. --- .../domain/clothing/entity/Clothing.java | 43 +++++++++++++++++++ .../clothing/entity/type/weatherType.java | 5 +++ .../coordination/entity/Coordination.java | 7 +++ .../entity/CoordinationClothing.java | 23 ++++++++++ 4 files changed, 78 insertions(+) create mode 100644 backend/src/main/java/com/itec0401/backend/domain/clothing/entity/Clothing.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/clothing/entity/type/weatherType.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/coordinationclothing/entity/CoordinationClothing.java diff --git a/backend/src/main/java/com/itec0401/backend/domain/clothing/entity/Clothing.java b/backend/src/main/java/com/itec0401/backend/domain/clothing/entity/Clothing.java new file mode 100644 index 0000000..dcf34d6 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/clothing/entity/Clothing.java @@ -0,0 +1,43 @@ +package com.itec0401.backend.domain.clothing.entity; + +import com.itec0401.backend.domain.clothing.entity.type.weatherType; +import com.itec0401.backend.domain.coordinationclothing.entity.CoordinationClothing; +import com.itec0401.backend.domain.user.entity.User; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +import java.util.List; + +@Entity +@Getter +@NoArgsConstructor +public class Clothing { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "clothing_id") + private Long id; + + @Enumerated(EnumType.STRING) + private weatherType weather; + + // 다른 특징들을 enum 화 할건지 테이블 만들어서 쓸 건지 결정 해야함! + private String category; + + private String subCategory; + + private String textile; + + private String pattern; + + private String baseColor; + + private String pointColor; + + @OneToMany(mappedBy = "clothing") + private List coordinationClothingList; + + @ManyToOne + @JoinColumn(name = "user_id") + private User user; + +} diff --git a/backend/src/main/java/com/itec0401/backend/domain/clothing/entity/type/weatherType.java b/backend/src/main/java/com/itec0401/backend/domain/clothing/entity/type/weatherType.java new file mode 100644 index 0000000..ac9c790 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/clothing/entity/type/weatherType.java @@ -0,0 +1,5 @@ +package com.itec0401.backend.domain.clothing.entity.type; + +public enum weatherType { + SPRING, SUMMER, AUTUMN, WINTER +} diff --git a/backend/src/main/java/com/itec0401/backend/domain/coordination/entity/Coordination.java b/backend/src/main/java/com/itec0401/backend/domain/coordination/entity/Coordination.java index 212341c..199ffc3 100644 --- a/backend/src/main/java/com/itec0401/backend/domain/coordination/entity/Coordination.java +++ b/backend/src/main/java/com/itec0401/backend/domain/coordination/entity/Coordination.java @@ -1,5 +1,6 @@ package com.itec0401.backend.domain.coordination.entity; +import com.itec0401.backend.domain.coordinationclothing.entity.CoordinationClothing; import com.itec0401.backend.domain.user.entity.User; import com.itec0401.backend.global.BaseEntity; import jakarta.persistence.*; @@ -7,6 +8,8 @@ import lombok.Getter; import lombok.NoArgsConstructor; +import java.util.List; + @Entity @Getter @NoArgsConstructor @@ -21,4 +24,8 @@ public class Coordination extends BaseEntity { @JoinColumn(name = "user_id", nullable = false) private User user; + @OneToMany(mappedBy = "coordination") + private List coordinationClothingList; + + } diff --git a/backend/src/main/java/com/itec0401/backend/domain/coordinationclothing/entity/CoordinationClothing.java b/backend/src/main/java/com/itec0401/backend/domain/coordinationclothing/entity/CoordinationClothing.java new file mode 100644 index 0000000..6fcdcd1 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/coordinationclothing/entity/CoordinationClothing.java @@ -0,0 +1,23 @@ +package com.itec0401.backend.domain.coordinationclothing.entity; + +import com.itec0401.backend.domain.clothing.entity.Clothing; +import com.itec0401.backend.domain.coordination.entity.Coordination; +import jakarta.persistence.*; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Entity +@Getter +@NoArgsConstructor +public class CoordinationClothing { + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) + private Long id; + + @ManyToOne + @JoinColumn(name = "clothing_id") + private Clothing clothing; + + @ManyToOne + @JoinColumn(name = "coordination_id") + private Coordination coordination; +} From 8898425b6313f759869849124a1fa530f5006e01 Mon Sep 17 00:00:00 2001 From: milk-stone Date: Sat, 12 Oct 2024 21:56:12 +0900 Subject: [PATCH 07/24] =?UTF-8?q?feat:=20User=20domain=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 마이페이지 열람 API 초안 구현 완료 --- .../backend/domain/color/entity/Color.java | 2 +- .../user/controller/UserController.java | 27 +++++++++ .../domain/user/dto/UpdateUserProfileDto.java | 21 +++++++ .../backend/domain/user/dto/UserInfoDto.java | 56 +++++++++++++++++++ .../domain/user/dto/UserRequestDto.java | 21 +++++++ .../backend/domain/user/entity/User.java | 32 ++++++++++- .../user/repository/UserRepository.java | 8 +++ .../domain/user/service/UserService.java | 24 ++++++++ 8 files changed, 188 insertions(+), 3 deletions(-) create mode 100644 backend/src/main/java/com/itec0401/backend/domain/user/controller/UserController.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/user/dto/UpdateUserProfileDto.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/user/dto/UserInfoDto.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/user/dto/UserRequestDto.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/user/repository/UserRepository.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/user/service/UserService.java diff --git a/backend/src/main/java/com/itec0401/backend/domain/color/entity/Color.java b/backend/src/main/java/com/itec0401/backend/domain/color/entity/Color.java index 782867d..3cac0df 100644 --- a/backend/src/main/java/com/itec0401/backend/domain/color/entity/Color.java +++ b/backend/src/main/java/com/itec0401/backend/domain/color/entity/Color.java @@ -16,7 +16,7 @@ public class Color extends BaseEntity { @Column(name = "color_id") private Long id; - private String style; + private String color; @OneToMany(mappedBy = "color") private List userColors; diff --git a/backend/src/main/java/com/itec0401/backend/domain/user/controller/UserController.java b/backend/src/main/java/com/itec0401/backend/domain/user/controller/UserController.java new file mode 100644 index 0000000..8ddb8fb --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/user/controller/UserController.java @@ -0,0 +1,27 @@ +package com.itec0401.backend.domain.user.controller; + +import com.itec0401.backend.domain.user.dto.UpdateUserProfileDto; +import com.itec0401.backend.domain.user.dto.UserInfoDto; +import com.itec0401.backend.domain.user.service.UserService; +import io.swagger.v3.oas.annotations.Operation; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequiredArgsConstructor +public class UserController { + private final UserService userService; + + @Operation(summary = "마이 페이지 열람") + @GetMapping("user/profile") + public ResponseEntity getUserProfile(@RequestParam Long user_id) { + return ResponseEntity.ok(userService.getUserProfile(user_id)); + } + + @Operation(summary = "마이 페이지 수정") + @PutMapping("user/profile") + public ResponseEntity updateUserProfile(@RequestParam Long user_id, @RequestBody UpdateUserProfileDto updateUserProfileDto) { + + } +} diff --git a/backend/src/main/java/com/itec0401/backend/domain/user/dto/UpdateUserProfileDto.java b/backend/src/main/java/com/itec0401/backend/domain/user/dto/UpdateUserProfileDto.java new file mode 100644 index 0000000..e8ab4ab --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/user/dto/UpdateUserProfileDto.java @@ -0,0 +1,21 @@ +package com.itec0401.backend.domain.user.dto; + +import lombok.Builder; +import lombok.Getter; + +import java.util.List; + +@Builder +@Getter +public class UpdateUserProfileDto { + private final String nickname; + + private final int gender; + private final int age; + private final double height; + private final double weight; + private final String tone; + + private final List colorList; + private final List styleList; +} diff --git a/backend/src/main/java/com/itec0401/backend/domain/user/dto/UserInfoDto.java b/backend/src/main/java/com/itec0401/backend/domain/user/dto/UserInfoDto.java new file mode 100644 index 0000000..bfff1ce --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/user/dto/UserInfoDto.java @@ -0,0 +1,56 @@ +package com.itec0401.backend.domain.user.dto; + +import com.itec0401.backend.domain.color.entity.Color; +import com.itec0401.backend.domain.style.entity.Style; +import com.itec0401.backend.domain.user.entity.User; +import com.itec0401.backend.domain.usercolor.entity.UserColor; +import com.itec0401.backend.domain.userstyle.entity.UserStyle; +import lombok.Builder; +import lombok.Getter; + +import java.util.List; +import java.util.stream.Collectors; + +@Builder +@Getter +public class UserInfoDto { + private final Long id; + private final String nickName; + + private final int gender; + private final int age; + private final double height; + private final double weight; + private final String tone; + + private final List colorList; + private final List styleList; + + public static UserInfoDto toDto(User user){ +// List userColors = user.getUserColorList().stream() +// .map(UserColor::getColor) +// .map(Color::getColor) +// .toList(); + List userColors = user.getUserColorList().stream() + .map(userColor -> userColor.getColor().getColor()) + .toList(); +// List userStyles = user.getUserStyleList().stream() +// .map(UserStyle::getStyle) +// .map(Style::getStyle) +// .toList(); + List userStyles = user.getUserStyleList().stream() + .map(userStyle -> userStyle.getStyle().getStyle()) + .toList(); + return UserInfoDto.builder() + .id(user.getId()) + .nickName(user.getNickname()) + .gender(user.getGender()) + .age(user.getAge()) + .height(user.getHeight()) + .weight(user.getWeight()) + .tone(user.getTone()) + .colorList(userColors) + .styleList(userStyles) + .build(); + } +} diff --git a/backend/src/main/java/com/itec0401/backend/domain/user/dto/UserRequestDto.java b/backend/src/main/java/com/itec0401/backend/domain/user/dto/UserRequestDto.java new file mode 100644 index 0000000..5df34af --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/user/dto/UserRequestDto.java @@ -0,0 +1,21 @@ +package com.itec0401.backend.domain.user.dto; + +import lombok.Builder; +import lombok.Getter; + +@Builder +@Getter +public class UserRequestDto { + private final String name; + private final String nickname; + private final String email; + + private final int gender; + private final int age; + private final double height; + private final double weight; + private final String tone; + + private final String color; + private final String style; +} diff --git a/backend/src/main/java/com/itec0401/backend/domain/user/entity/User.java b/backend/src/main/java/com/itec0401/backend/domain/user/entity/User.java index 4132ecf..d2ccbca 100644 --- a/backend/src/main/java/com/itec0401/backend/domain/user/entity/User.java +++ b/backend/src/main/java/com/itec0401/backend/domain/user/entity/User.java @@ -1,10 +1,12 @@ package com.itec0401.backend.domain.user.entity; import com.itec0401.backend.domain.coordination.entity.Coordination; +import com.itec0401.backend.domain.user.dto.UserRequestDto; import com.itec0401.backend.domain.usercolor.entity.UserColor; import com.itec0401.backend.domain.userstyle.entity.UserStyle; import com.itec0401.backend.global.BaseEntityWithUpdatedAt; import jakarta.persistence.*; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -27,6 +29,8 @@ public class User extends BaseEntityWithUpdatedAt { // google login API 보고 email, password 필드 생각 다시 해야함 // google 로그인 하면 이메일, 닉네임 받아올 수 있으려나? + private String email; + // 유저 추가 정보 private int gender; private int age; @@ -34,8 +38,6 @@ public class User extends BaseEntityWithUpdatedAt { private double weight; private String tone; - // mapping - @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) private List coordinationList; @@ -44,4 +46,30 @@ public class User extends BaseEntityWithUpdatedAt { @OneToMany(mappedBy = "user", cascade = CascadeType.ALL) private List userColorList; + + public static User toEntity(UserRequestDto userRequestDto) { + return User.builder() + .name(userRequestDto.getName()) + .nickname(userRequestDto.getNickname()) + .email(userRequestDto.getEmail()) + .gender(userRequestDto.getGender()) + .age(userRequestDto.getAge()) + .height(userRequestDto.getHeight()) + .weight(userRequestDto.getWeight()) + .tone(userRequestDto.getTone()) + .build(); + } + + @Builder + public User(String name, String nickname, String email, int gender, int age, double height, double weight, String tone) { + this.name = name; + this.nickname = nickname; + this.email = email; + this.gender = gender; + this.age = age; + this.height = height; + this.weight = weight; + this.tone = tone; + // color, style 매핑 해야함 + } } diff --git a/backend/src/main/java/com/itec0401/backend/domain/user/repository/UserRepository.java b/backend/src/main/java/com/itec0401/backend/domain/user/repository/UserRepository.java new file mode 100644 index 0000000..bc7027f --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/user/repository/UserRepository.java @@ -0,0 +1,8 @@ +package com.itec0401.backend.domain.user.repository; + +import com.itec0401.backend.domain.user.entity.User; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +public interface UserRepository extends JpaRepository { +} diff --git a/backend/src/main/java/com/itec0401/backend/domain/user/service/UserService.java b/backend/src/main/java/com/itec0401/backend/domain/user/service/UserService.java new file mode 100644 index 0000000..9e290ea --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/user/service/UserService.java @@ -0,0 +1,24 @@ +package com.itec0401.backend.domain.user.service; + +import com.itec0401.backend.domain.user.dto.UserInfoDto; +import com.itec0401.backend.domain.user.entity.User; +import com.itec0401.backend.domain.user.repository.UserRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class UserService { + private final UserRepository userRepository; + + public UserInfoDto getUserProfile(Long id){ + User user = userRepository.findById(id).orElse(null); + if (user == null){ + return null; + } + else { + return UserInfoDto.toDto(user); + } + } + +} From 661a139a420d671786102bef5086cbeb744db45f Mon Sep 17 00:00:00 2001 From: LeeDongjae Date: Sat, 12 Oct 2024 23:06:08 +0900 Subject: [PATCH 08/24] =?UTF-8?q?Feat:=20"=ED=9A=8C=EC=9B=90=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20=EA=B5=AC=ED=98=84"?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 회원 가입, 이메일 중복 확인, 로그인 API 개발 완료 구글 소셜 로그인에서 자체 로그인으로 변경되었음 --- backend/build.gradle | 6 +- .../backend/config/SecurityConfig.java | 28 ++++++++ .../login/controller/LoginController.java | 17 ----- .../backend/login/service/LoginService.java | 5 -- .../login/service/LoginServiceImpl.java | 12 ---- .../member/controller/MemberController.java | 39 +++++++++++ .../backend/member/dto/LoginRequestDTO.java | 15 ++++ .../backend/member/dto/LoginResponseDTO.java | 14 ++++ .../backend/member/dto/MemberDTO.java | 16 +++++ .../backend/member/entity/MemberEntity.java | 29 ++++++++ .../backend/member/jwt/JwtFilter.java | 62 +++++++++++++++++ .../backend/member/jwt/JwtTokenProvider.java | 60 ++++++++++++++++ .../member/repository/MemberRepository.java | 14 ++++ .../backend/member/service/MemberService.java | 14 ++++ .../member/service/MemberServiceImpl.java | 68 +++++++++++++++++++ backend/src/main/resources/application.yml | 2 + 16 files changed, 365 insertions(+), 36 deletions(-) create mode 100644 backend/src/main/java/com/itec0401/backend/config/SecurityConfig.java delete mode 100644 backend/src/main/java/com/itec0401/backend/login/controller/LoginController.java delete mode 100644 backend/src/main/java/com/itec0401/backend/login/service/LoginService.java delete mode 100644 backend/src/main/java/com/itec0401/backend/login/service/LoginServiceImpl.java create mode 100644 backend/src/main/java/com/itec0401/backend/member/controller/MemberController.java create mode 100644 backend/src/main/java/com/itec0401/backend/member/dto/LoginRequestDTO.java create mode 100644 backend/src/main/java/com/itec0401/backend/member/dto/LoginResponseDTO.java create mode 100644 backend/src/main/java/com/itec0401/backend/member/dto/MemberDTO.java create mode 100644 backend/src/main/java/com/itec0401/backend/member/entity/MemberEntity.java create mode 100644 backend/src/main/java/com/itec0401/backend/member/jwt/JwtFilter.java create mode 100644 backend/src/main/java/com/itec0401/backend/member/jwt/JwtTokenProvider.java create mode 100644 backend/src/main/java/com/itec0401/backend/member/repository/MemberRepository.java create mode 100644 backend/src/main/java/com/itec0401/backend/member/service/MemberService.java create mode 100644 backend/src/main/java/com/itec0401/backend/member/service/MemberServiceImpl.java diff --git a/backend/build.gradle b/backend/build.gradle index de7c91e..6130389 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -25,16 +25,18 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-data-jpa' - //implementation 'org.springframework.boot:spring-boot-starter-security' + implementation 'org.springframework.boot:spring-boot-starter-security' implementation 'org.springframework.boot:spring-boot-starter-web' implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' compileOnly 'org.projectlombok:lombok' runtimeOnly 'com.mysql:mysql-connector-j' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' - //testImplementation 'org.springframework.security:spring-security-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + //JWT + implementation 'io.jsonwebtoken:jjwt:0.9.1' + // Swagger implementation 'org.springdoc:springdoc-openapi-starter-webmvc-ui:2.3.0' } diff --git a/backend/src/main/java/com/itec0401/backend/config/SecurityConfig.java b/backend/src/main/java/com/itec0401/backend/config/SecurityConfig.java new file mode 100644 index 0000000..c38b0ad --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/config/SecurityConfig.java @@ -0,0 +1,28 @@ +package com.itec0401.backend.config; + +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.crypto.bcrypt.BCryptPasswordEncoder; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.security.web.SecurityFilterChain; + +@Configuration +@EnableWebSecurity +public class SecurityConfig { + + @Bean + public SecurityFilterChain securityFilterChain(HttpSecurity http) throws Exception { + http + .csrf((csrf) -> csrf.disable()) + .cors((c) -> c.disable()) + .headers((headers) -> headers.disable()); + return http.build(); + } + + @Bean + public PasswordEncoder passwordEncoder(){ + return new BCryptPasswordEncoder(); + } +} \ No newline at end of file diff --git a/backend/src/main/java/com/itec0401/backend/login/controller/LoginController.java b/backend/src/main/java/com/itec0401/backend/login/controller/LoginController.java deleted file mode 100644 index 4bc37bf..0000000 --- a/backend/src/main/java/com/itec0401/backend/login/controller/LoginController.java +++ /dev/null @@ -1,17 +0,0 @@ -package com.itec0401.backend.login.controller; - -import com.itec0401.backend.login.service.LoginService; -import lombok.RequiredArgsConstructor; -import org.springframework.web.bind.annotation.*; - -@RestController -@RequestMapping(value = "/login/oauth2", produces = "application/json") -@RequiredArgsConstructor -public class LoginController { - private final LoginService loginService; - - @GetMapping("/code/{registrationId}") - public void oauthLogin(@RequestParam String code, @PathVariable String registrationId) { - loginService.oauthLogin(code, registrationId); - } -} diff --git a/backend/src/main/java/com/itec0401/backend/login/service/LoginService.java b/backend/src/main/java/com/itec0401/backend/login/service/LoginService.java deleted file mode 100644 index 611f5ce..0000000 --- a/backend/src/main/java/com/itec0401/backend/login/service/LoginService.java +++ /dev/null @@ -1,5 +0,0 @@ -package com.itec0401.backend.login.service; - -public interface LoginService { - void oauthLogin(String code, String registrationId); -} diff --git a/backend/src/main/java/com/itec0401/backend/login/service/LoginServiceImpl.java b/backend/src/main/java/com/itec0401/backend/login/service/LoginServiceImpl.java deleted file mode 100644 index abe9899..0000000 --- a/backend/src/main/java/com/itec0401/backend/login/service/LoginServiceImpl.java +++ /dev/null @@ -1,12 +0,0 @@ -package com.itec0401.backend.login.service; - -import org.springframework.stereotype.Service; - -@Service -public class LoginServiceImpl implements LoginService{ - @Override - public void oauthLogin(String code, String registrationId) { - System.out.println("code = " + code); - System.out.println("registrationId = " + registrationId); - } -} diff --git a/backend/src/main/java/com/itec0401/backend/member/controller/MemberController.java b/backend/src/main/java/com/itec0401/backend/member/controller/MemberController.java new file mode 100644 index 0000000..944e359 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/member/controller/MemberController.java @@ -0,0 +1,39 @@ +package com.itec0401.backend.member.controller; + +import com.itec0401.backend.member.dto.LoginResponseDTO; +import com.itec0401.backend.member.dto.LoginRequestDTO; +import com.itec0401.backend.member.dto.MemberDTO; +import com.itec0401.backend.member.repository.MemberRepository; +import com.itec0401.backend.member.service.MemberService; +import lombok.RequiredArgsConstructor; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +@RestController +@RequestMapping(value = "/member") +@RequiredArgsConstructor +public class MemberController { + + private final MemberService memberService; + private final MemberRepository memberRepository; + + /** + * @param loginRequestDTO + * @return AccessToken 반환 + */ + @PostMapping("/login") + public ResponseEntity login(@RequestBody LoginRequestDTO loginRequestDTO){ + return memberService.login(loginRequestDTO); + } + + @PostMapping("/new") + public ResponseEntity signIn(@RequestBody MemberDTO memberDTO){ + return memberService.signIn(memberDTO); + } + + //아이디 체크 + @GetMapping("/email/{email}") + public ResponseEntity checkEmail(@RequestParam String email){ + return memberService.checkEmail(email); + } +} diff --git a/backend/src/main/java/com/itec0401/backend/member/dto/LoginRequestDTO.java b/backend/src/main/java/com/itec0401/backend/member/dto/LoginRequestDTO.java new file mode 100644 index 0000000..6e68634 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/member/dto/LoginRequestDTO.java @@ -0,0 +1,15 @@ +package com.itec0401.backend.member.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class LoginRequestDTO { + private String email; + private String password; +} diff --git a/backend/src/main/java/com/itec0401/backend/member/dto/LoginResponseDTO.java b/backend/src/main/java/com/itec0401/backend/member/dto/LoginResponseDTO.java new file mode 100644 index 0000000..7504816 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/member/dto/LoginResponseDTO.java @@ -0,0 +1,14 @@ +package com.itec0401.backend.member.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Data +@AllArgsConstructor +@NoArgsConstructor +@Builder +public class LoginResponseDTO { + private String accessToken; +} diff --git a/backend/src/main/java/com/itec0401/backend/member/dto/MemberDTO.java b/backend/src/main/java/com/itec0401/backend/member/dto/MemberDTO.java new file mode 100644 index 0000000..4812887 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/member/dto/MemberDTO.java @@ -0,0 +1,16 @@ +package com.itec0401.backend.member.dto; + +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Getter; +import lombok.NoArgsConstructor; + +@Getter +@NoArgsConstructor +@AllArgsConstructor +@Builder +public class MemberDTO { + private String email; + private String username; + private String password; +} diff --git a/backend/src/main/java/com/itec0401/backend/member/entity/MemberEntity.java b/backend/src/main/java/com/itec0401/backend/member/entity/MemberEntity.java new file mode 100644 index 0000000..dedb85d --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/member/entity/MemberEntity.java @@ -0,0 +1,29 @@ +package com.itec0401.backend.member.entity; + +import jakarta.persistence.*; +import lombok.AllArgsConstructor; +import lombok.Builder; +import lombok.Data; +import lombok.NoArgsConstructor; + +@Entity +@Data +@Builder +@AllArgsConstructor +@NoArgsConstructor +@Table(name = "MEMBER") +public class MemberEntity { + + @Id // 내가 PK + @GeneratedValue(strategy = GenerationType.IDENTITY) // 자동 id 생성 + private Long id; + + @Column(nullable = false, unique = true) + private String email; + + @Column + private String username; + + @Column(nullable = false) + private String password; +} diff --git a/backend/src/main/java/com/itec0401/backend/member/jwt/JwtFilter.java b/backend/src/main/java/com/itec0401/backend/member/jwt/JwtFilter.java new file mode 100644 index 0000000..b105f6b --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/member/jwt/JwtFilter.java @@ -0,0 +1,62 @@ +package com.itec0401.backend.member.jwt; + +import io.jsonwebtoken.ExpiredJwtException; +import io.jsonwebtoken.JwtException; +import jakarta.servlet.FilterChain; +import jakarta.servlet.ServletException; +import jakarta.servlet.http.HttpServletRequest; +import jakarta.servlet.http.HttpServletResponse; +import lombok.RequiredArgsConstructor; +import org.springframework.http.HttpHeaders; +import org.springframework.security.authentication.UsernamePasswordAuthenticationToken; +import org.springframework.security.core.authority.SimpleGrantedAuthority; +import org.springframework.security.core.context.SecurityContextHolder; +import org.springframework.stereotype.Component; +import org.springframework.web.filter.OncePerRequestFilter; + +import java.io.IOException; +import java.util.List; + +@RequiredArgsConstructor +@Component +public class JwtFilter extends OncePerRequestFilter { + + private final JwtTokenProvider jwtTokenProvider; + + @Override + protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException { + String authorization = request.getHeader(HttpHeaders.AUTHORIZATION); + + if(authorization == null || !authorization.startsWith("Bearer ")) { + filterChain.doFilter(request, response); + return; + } + String token = authorization.split(" ")[1]; + + try { + // JWT 토큰 유효성 검사 + if (!jwtTokenProvider.isAccessToken(token)) { + filterChain.doFilter(request, response); + return; + } + } catch (ExpiredJwtException e) { + // 만료된 토큰에 대한 처리 + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.getWriter().write("Token has expired"); + return; + } catch (JwtException | IllegalArgumentException e) { + // 기타 JWT 관련 예외 처리 + response.setStatus(HttpServletResponse.SC_UNAUTHORIZED); + response.getWriter().write("Invalid token"); + return; + } + + String email = jwtTokenProvider.getEmail(token); + + UsernamePasswordAuthenticationToken usernamePasswordAuthenticationToken = + new UsernamePasswordAuthenticationToken(email, null, List.of(new SimpleGrantedAuthority("USER"))); + + SecurityContextHolder.getContext().setAuthentication(usernamePasswordAuthenticationToken); + filterChain.doFilter(request, response); + } +} diff --git a/backend/src/main/java/com/itec0401/backend/member/jwt/JwtTokenProvider.java b/backend/src/main/java/com/itec0401/backend/member/jwt/JwtTokenProvider.java new file mode 100644 index 0000000..34ebc0d --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/member/jwt/JwtTokenProvider.java @@ -0,0 +1,60 @@ +package com.itec0401.backend.member.jwt; + +import io.jsonwebtoken.Claims; +import io.jsonwebtoken.Jwts; +import io.jsonwebtoken.MalformedJwtException; +import io.jsonwebtoken.SignatureAlgorithm; +import lombok.RequiredArgsConstructor; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.time.Duration; +import java.util.Date; + +@Component +@RequiredArgsConstructor +public class JwtTokenProvider { + + private static final Long accessTokenValidTime = Duration.ofHours(2).toMillis(); + private static final Long refreshTokenValidTime = Duration.ofDays(7).toMillis(); + + @Value("${JWT.SECRET-KEY}") + private String secretKey; + + + public String getEmail(String token){ + return Jwts.parser() + .setSigningKey(secretKey) + .parseClaimsJws(token) + .getBody() + .get("email", String.class); + } + + public boolean isAccessToken(String token) throws MalformedJwtException { + return Jwts.parser() + .setSigningKey(secretKey) + .parseClaimsJws(token) + .getHeader().get("type").toString().equals("access"); + } + + public String createAccessToken(String email){ + return createJwtToken(email, secretKey, "access", accessTokenValidTime); + } + + public String createRefreshToken(String email){ + return createJwtToken(email, secretKey, "refresh", refreshTokenValidTime); + } + + private String createJwtToken(String email, String secretKey, String type, Long tokenValidTime){ + Claims claims = Jwts.claims(); + claims.put("email", email); + + return Jwts.builder() + .setHeaderParam("type", type) + .setClaims(claims) + .setIssuedAt(new Date(System.currentTimeMillis())) + .setExpiration(new Date(System.currentTimeMillis() + tokenValidTime)) + .signWith(SignatureAlgorithm.HS256, secretKey) + .compact(); + } +} diff --git a/backend/src/main/java/com/itec0401/backend/member/repository/MemberRepository.java b/backend/src/main/java/com/itec0401/backend/member/repository/MemberRepository.java new file mode 100644 index 0000000..b350dff --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/member/repository/MemberRepository.java @@ -0,0 +1,14 @@ +package com.itec0401.backend.member.repository; + +import com.itec0401.backend.member.entity.MemberEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface MemberRepository extends JpaRepository { + + Optional findByEmail(String email); + +} diff --git a/backend/src/main/java/com/itec0401/backend/member/service/MemberService.java b/backend/src/main/java/com/itec0401/backend/member/service/MemberService.java new file mode 100644 index 0000000..75578d9 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/member/service/MemberService.java @@ -0,0 +1,14 @@ +package com.itec0401.backend.member.service; + +import com.itec0401.backend.member.dto.LoginRequestDTO; +import com.itec0401.backend.member.dto.LoginResponseDTO; +import com.itec0401.backend.member.dto.MemberDTO; +import org.springframework.http.ResponseEntity; + +public interface MemberService { + ResponseEntity login(LoginRequestDTO loginRequestDTO); + + ResponseEntity signIn(MemberDTO memberDTO); + + ResponseEntity checkEmail(String email); +} diff --git a/backend/src/main/java/com/itec0401/backend/member/service/MemberServiceImpl.java b/backend/src/main/java/com/itec0401/backend/member/service/MemberServiceImpl.java new file mode 100644 index 0000000..e0ab943 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/member/service/MemberServiceImpl.java @@ -0,0 +1,68 @@ +package com.itec0401.backend.member.service; + +import com.itec0401.backend.member.dto.LoginRequestDTO; +import com.itec0401.backend.member.dto.LoginResponseDTO; +import com.itec0401.backend.member.dto.MemberDTO; +import com.itec0401.backend.member.entity.MemberEntity; +import com.itec0401.backend.member.jwt.JwtTokenProvider; +import com.itec0401.backend.member.repository.MemberRepository; +import lombok.RequiredArgsConstructor; +import lombok.extern.slf4j.Slf4j; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.security.crypto.password.PasswordEncoder; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +@RequiredArgsConstructor +@Slf4j +public class MemberServiceImpl implements MemberService{ + + private final JwtTokenProvider jwtTokenProvider; + private final MemberRepository memberRepository; + private final PasswordEncoder passwordEncoder; + + @Override + public ResponseEntity login(LoginRequestDTO loginRequestDTO) { + //AccessToken 만들어서 줘야함 + Optional byEmail = memberRepository.findByEmail(loginRequestDTO.getEmail()); + if (byEmail.isEmpty()){ + return new ResponseEntity<>(HttpStatus.NOT_FOUND); + } else if (!passwordEncoder.matches(loginRequestDTO.getPassword(), byEmail.get().getPassword())) { + return new ResponseEntity<>(HttpStatus.UNAUTHORIZED); + } else { + LoginResponseDTO loginResponseDTO = LoginResponseDTO.builder(). + accessToken(jwtTokenProvider.createAccessToken(loginRequestDTO.getEmail())) + .build(); + return new ResponseEntity<>(loginResponseDTO, HttpStatus.OK); + } + } + + @Override + public ResponseEntity signIn(MemberDTO memberDTO) { + try { + // 비밀번호 인코딩 + String encoded = passwordEncoder.encode(memberDTO.getPassword()); + + // 회원 저장 + MemberEntity saved = memberRepository.save(MemberEntity.builder() + .email(memberDTO.getEmail()) + .username(memberDTO.getUsername()) + .password(encoded) + .build()); + + // 저장된 객체가 null인 경우 처리 + return new ResponseEntity<>("회원가입 완료", HttpStatus.OK); // 성공 시 200 반환 + } catch (Exception e) { + // 예외 발생 시 처리 + return new ResponseEntity<>("회원가입 실패", HttpStatus.BAD_REQUEST); // 이메일 조회 후 회원가입 할것 + } + } + + @Override + public ResponseEntity checkEmail(String email) { + return new ResponseEntity<>(memberRepository.findByEmail(email).isPresent(), HttpStatus.OK); + } +} diff --git a/backend/src/main/resources/application.yml b/backend/src/main/resources/application.yml index c77f09b..b4357f9 100644 --- a/backend/src/main/resources/application.yml +++ b/backend/src/main/resources/application.yml @@ -32,6 +32,8 @@ logging: level: org.hibernate.SQL: DEBUG org.hibernate.type: TRACE + org.springframework.security: TRACE + server: servlet: From 89973d8db400149d4423842fd1221826340095f3 Mon Sep 17 00:00:00 2001 From: LeeDongjae Date: Sun, 13 Oct 2024 00:09:51 +0900 Subject: [PATCH 09/24] =?UTF-8?q?Refactor:=20develop=20=EB=B8=8C=EB=9E=9C?= =?UTF-8?q?=EC=B9=98=20merge=20=ED=9B=84=20=EB=A6=AC=ED=8C=A9=ED=86=A0?= =?UTF-8?q?=EB=A7=81?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Member 패키지 내용을 User 패키지로 옮김 UserRepository 메소드 생성 --- backend/build.gradle | 1 + .../user/controller/UserController.java | 26 ++++++++--- .../user}/dto/LoginRequestDTO.java | 2 +- .../user}/dto/LoginResponseDTO.java | 2 +- .../user}/dto/MemberDTO.java | 5 ++- .../backend/domain/user/entity/User.java | 14 +++++- .../user}/jwt/JwtFilter.java | 2 +- .../user}/jwt/JwtTokenProvider.java | 2 +- .../user/repository/UserRepository.java | 4 +- .../domain/user/service/UserService.java | 32 +++++--------- .../user/service/UserServiceImpl.java} | 44 ++++++++++++------- .../member/controller/MemberController.java | 39 ---------------- .../backend/member/entity/MemberEntity.java | 29 ------------ .../member/repository/MemberRepository.java | 14 ------ .../backend/member/service/MemberService.java | 14 ------ 15 files changed, 82 insertions(+), 148 deletions(-) rename backend/src/main/java/com/itec0401/backend/{member => domain/user}/dto/LoginRequestDTO.java (84%) rename backend/src/main/java/com/itec0401/backend/{member => domain/user}/dto/LoginResponseDTO.java (83%) rename backend/src/main/java/com/itec0401/backend/{member => domain/user}/dto/MemberDTO.java (71%) rename backend/src/main/java/com/itec0401/backend/{member => domain/user}/jwt/JwtFilter.java (98%) rename backend/src/main/java/com/itec0401/backend/{member => domain/user}/jwt/JwtTokenProvider.java (97%) rename backend/src/main/java/com/itec0401/backend/{member/service/MemberServiceImpl.java => domain/user/service/UserServiceImpl.java} (59%) delete mode 100644 backend/src/main/java/com/itec0401/backend/member/controller/MemberController.java delete mode 100644 backend/src/main/java/com/itec0401/backend/member/entity/MemberEntity.java delete mode 100644 backend/src/main/java/com/itec0401/backend/member/repository/MemberRepository.java delete mode 100644 backend/src/main/java/com/itec0401/backend/member/service/MemberService.java diff --git a/backend/build.gradle b/backend/build.gradle index 6130389..1dfb888 100644 --- a/backend/build.gradle +++ b/backend/build.gradle @@ -33,6 +33,7 @@ dependencies { annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' testRuntimeOnly 'org.junit.platform:junit-platform-launcher' + implementation 'javax.xml.bind:jaxb-api:2.3.1' //JWT implementation 'io.jsonwebtoken:jjwt:0.9.1' diff --git a/backend/src/main/java/com/itec0401/backend/domain/user/controller/UserController.java b/backend/src/main/java/com/itec0401/backend/domain/user/controller/UserController.java index 8ddb8fb..72c1645 100644 --- a/backend/src/main/java/com/itec0401/backend/domain/user/controller/UserController.java +++ b/backend/src/main/java/com/itec0401/backend/domain/user/controller/UserController.java @@ -1,7 +1,6 @@ package com.itec0401.backend.domain.user.controller; -import com.itec0401.backend.domain.user.dto.UpdateUserProfileDto; -import com.itec0401.backend.domain.user.dto.UserInfoDto; +import com.itec0401.backend.domain.user.dto.*; import com.itec0401.backend.domain.user.service.UserService; import io.swagger.v3.oas.annotations.Operation; import lombok.RequiredArgsConstructor; @@ -10,18 +9,35 @@ @RestController @RequiredArgsConstructor +@RequestMapping("/api/v1/user") public class UserController { private final UserService userService; @Operation(summary = "마이 페이지 열람") - @GetMapping("user/profile") + @GetMapping("/profile") public ResponseEntity getUserProfile(@RequestParam Long user_id) { return ResponseEntity.ok(userService.getUserProfile(user_id)); } @Operation(summary = "마이 페이지 수정") - @PutMapping("user/profile") + @PutMapping("/profile") public ResponseEntity updateUserProfile(@RequestParam Long user_id, @RequestBody UpdateUserProfileDto updateUserProfileDto) { + return null; + } + + @PostMapping("/login") + public ResponseEntity login(@RequestBody LoginRequestDTO loginRequestDTO){ + return userService.login(loginRequestDTO); + } + + @PostMapping("/new") + public ResponseEntity signIn(@RequestBody MemberDTO memberDTO){ + return userService.signIn(memberDTO); + } + //아이디 체크 + @GetMapping("/email/{email}") + public ResponseEntity isEmailEmpty(@PathVariable String email){ + return userService.isEmailEmpty(email); } -} +} \ No newline at end of file diff --git a/backend/src/main/java/com/itec0401/backend/member/dto/LoginRequestDTO.java b/backend/src/main/java/com/itec0401/backend/domain/user/dto/LoginRequestDTO.java similarity index 84% rename from backend/src/main/java/com/itec0401/backend/member/dto/LoginRequestDTO.java rename to backend/src/main/java/com/itec0401/backend/domain/user/dto/LoginRequestDTO.java index 6e68634..9860149 100644 --- a/backend/src/main/java/com/itec0401/backend/member/dto/LoginRequestDTO.java +++ b/backend/src/main/java/com/itec0401/backend/domain/user/dto/LoginRequestDTO.java @@ -1,4 +1,4 @@ -package com.itec0401.backend.member.dto; +package com.itec0401.backend.domain.user.dto; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/backend/src/main/java/com/itec0401/backend/member/dto/LoginResponseDTO.java b/backend/src/main/java/com/itec0401/backend/domain/user/dto/LoginResponseDTO.java similarity index 83% rename from backend/src/main/java/com/itec0401/backend/member/dto/LoginResponseDTO.java rename to backend/src/main/java/com/itec0401/backend/domain/user/dto/LoginResponseDTO.java index 7504816..d6391e6 100644 --- a/backend/src/main/java/com/itec0401/backend/member/dto/LoginResponseDTO.java +++ b/backend/src/main/java/com/itec0401/backend/domain/user/dto/LoginResponseDTO.java @@ -1,4 +1,4 @@ -package com.itec0401.backend.member.dto; +package com.itec0401.backend.domain.user.dto; import lombok.AllArgsConstructor; import lombok.Builder; diff --git a/backend/src/main/java/com/itec0401/backend/member/dto/MemberDTO.java b/backend/src/main/java/com/itec0401/backend/domain/user/dto/MemberDTO.java similarity index 71% rename from backend/src/main/java/com/itec0401/backend/member/dto/MemberDTO.java rename to backend/src/main/java/com/itec0401/backend/domain/user/dto/MemberDTO.java index 4812887..dcbe12c 100644 --- a/backend/src/main/java/com/itec0401/backend/member/dto/MemberDTO.java +++ b/backend/src/main/java/com/itec0401/backend/domain/user/dto/MemberDTO.java @@ -1,4 +1,4 @@ -package com.itec0401.backend.member.dto; +package com.itec0401.backend.domain.user.dto; import lombok.AllArgsConstructor; import lombok.Builder; @@ -10,7 +10,8 @@ @AllArgsConstructor @Builder public class MemberDTO { + private String name; private String email; - private String username; + private String nickName; private String password; } diff --git a/backend/src/main/java/com/itec0401/backend/domain/user/entity/User.java b/backend/src/main/java/com/itec0401/backend/domain/user/entity/User.java index d2ccbca..9044860 100644 --- a/backend/src/main/java/com/itec0401/backend/domain/user/entity/User.java +++ b/backend/src/main/java/com/itec0401/backend/domain/user/entity/User.java @@ -6,6 +6,7 @@ import com.itec0401.backend.domain.userstyle.entity.UserStyle; import com.itec0401.backend.global.BaseEntityWithUpdatedAt; import jakarta.persistence.*; +import lombok.AllArgsConstructor; import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -14,7 +15,9 @@ @Entity @Getter +@AllArgsConstructor @NoArgsConstructor +@Builder public class User extends BaseEntityWithUpdatedAt { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "user_id") @@ -26,11 +29,15 @@ public class User extends BaseEntityWithUpdatedAt { @Column(nullable = false) private String nickname; + @Column(nullable = false, unique = true) + private String email; + + @Column(nullable = false) + private String password; + // google login API 보고 email, password 필드 생각 다시 해야함 // google 로그인 하면 이메일, 닉네임 받아올 수 있으려나? - private String email; - // 유저 추가 정보 private int gender; private int age; @@ -73,3 +80,6 @@ public User(String name, String nickname, String email, int gender, int age, dou // color, style 매핑 해야함 } } + + + diff --git a/backend/src/main/java/com/itec0401/backend/member/jwt/JwtFilter.java b/backend/src/main/java/com/itec0401/backend/domain/user/jwt/JwtFilter.java similarity index 98% rename from backend/src/main/java/com/itec0401/backend/member/jwt/JwtFilter.java rename to backend/src/main/java/com/itec0401/backend/domain/user/jwt/JwtFilter.java index b105f6b..eaed93f 100644 --- a/backend/src/main/java/com/itec0401/backend/member/jwt/JwtFilter.java +++ b/backend/src/main/java/com/itec0401/backend/domain/user/jwt/JwtFilter.java @@ -1,4 +1,4 @@ -package com.itec0401.backend.member.jwt; +package com.itec0401.backend.domain.user.jwt; import io.jsonwebtoken.ExpiredJwtException; import io.jsonwebtoken.JwtException; diff --git a/backend/src/main/java/com/itec0401/backend/member/jwt/JwtTokenProvider.java b/backend/src/main/java/com/itec0401/backend/domain/user/jwt/JwtTokenProvider.java similarity index 97% rename from backend/src/main/java/com/itec0401/backend/member/jwt/JwtTokenProvider.java rename to backend/src/main/java/com/itec0401/backend/domain/user/jwt/JwtTokenProvider.java index 34ebc0d..b698865 100644 --- a/backend/src/main/java/com/itec0401/backend/member/jwt/JwtTokenProvider.java +++ b/backend/src/main/java/com/itec0401/backend/domain/user/jwt/JwtTokenProvider.java @@ -1,4 +1,4 @@ -package com.itec0401.backend.member.jwt; +package com.itec0401.backend.domain.user.jwt; import io.jsonwebtoken.Claims; import io.jsonwebtoken.Jwts; diff --git a/backend/src/main/java/com/itec0401/backend/domain/user/repository/UserRepository.java b/backend/src/main/java/com/itec0401/backend/domain/user/repository/UserRepository.java index bc7027f..6ec3dd9 100644 --- a/backend/src/main/java/com/itec0401/backend/domain/user/repository/UserRepository.java +++ b/backend/src/main/java/com/itec0401/backend/domain/user/repository/UserRepository.java @@ -2,7 +2,9 @@ import com.itec0401.backend.domain.user.entity.User; import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; + +import java.util.Optional; public interface UserRepository extends JpaRepository { + Optional findByEmail(String email); } diff --git a/backend/src/main/java/com/itec0401/backend/domain/user/service/UserService.java b/backend/src/main/java/com/itec0401/backend/domain/user/service/UserService.java index 9e290ea..d27f5d8 100644 --- a/backend/src/main/java/com/itec0401/backend/domain/user/service/UserService.java +++ b/backend/src/main/java/com/itec0401/backend/domain/user/service/UserService.java @@ -1,24 +1,14 @@ package com.itec0401.backend.domain.user.service; +import com.itec0401.backend.domain.user.dto.LoginRequestDTO; +import com.itec0401.backend.domain.user.dto.LoginResponseDTO; +import com.itec0401.backend.domain.user.dto.MemberDTO; import com.itec0401.backend.domain.user.dto.UserInfoDto; -import com.itec0401.backend.domain.user.entity.User; -import com.itec0401.backend.domain.user.repository.UserRepository; -import lombok.RequiredArgsConstructor; -import org.springframework.stereotype.Service; - -@Service -@RequiredArgsConstructor -public class UserService { - private final UserRepository userRepository; - - public UserInfoDto getUserProfile(Long id){ - User user = userRepository.findById(id).orElse(null); - if (user == null){ - return null; - } - else { - return UserInfoDto.toDto(user); - } - } - -} +import org.springframework.http.ResponseEntity; + +public interface UserService { + UserInfoDto getUserProfile(Long id); + ResponseEntity login(LoginRequestDTO loginRequestDTO); + ResponseEntity signIn(MemberDTO memberDTO); + ResponseEntity isEmailEmpty(String email); +} \ No newline at end of file diff --git a/backend/src/main/java/com/itec0401/backend/member/service/MemberServiceImpl.java b/backend/src/main/java/com/itec0401/backend/domain/user/service/UserServiceImpl.java similarity index 59% rename from backend/src/main/java/com/itec0401/backend/member/service/MemberServiceImpl.java rename to backend/src/main/java/com/itec0401/backend/domain/user/service/UserServiceImpl.java index e0ab943..bfcc60d 100644 --- a/backend/src/main/java/com/itec0401/backend/member/service/MemberServiceImpl.java +++ b/backend/src/main/java/com/itec0401/backend/domain/user/service/UserServiceImpl.java @@ -1,13 +1,13 @@ -package com.itec0401.backend.member.service; +package com.itec0401.backend.domain.user.service; -import com.itec0401.backend.member.dto.LoginRequestDTO; -import com.itec0401.backend.member.dto.LoginResponseDTO; -import com.itec0401.backend.member.dto.MemberDTO; -import com.itec0401.backend.member.entity.MemberEntity; -import com.itec0401.backend.member.jwt.JwtTokenProvider; -import com.itec0401.backend.member.repository.MemberRepository; +import com.itec0401.backend.domain.user.dto.LoginRequestDTO; +import com.itec0401.backend.domain.user.dto.LoginResponseDTO; +import com.itec0401.backend.domain.user.dto.MemberDTO; +import com.itec0401.backend.domain.user.dto.UserInfoDto; +import com.itec0401.backend.domain.user.entity.User; +import com.itec0401.backend.domain.user.jwt.JwtTokenProvider; +import com.itec0401.backend.domain.user.repository.UserRepository; import lombok.RequiredArgsConstructor; -import lombok.extern.slf4j.Slf4j; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.crypto.password.PasswordEncoder; @@ -17,17 +17,25 @@ @Service @RequiredArgsConstructor -@Slf4j -public class MemberServiceImpl implements MemberService{ - +public class UserServiceImpl implements UserService{ + private final UserRepository userRepository; private final JwtTokenProvider jwtTokenProvider; - private final MemberRepository memberRepository; private final PasswordEncoder passwordEncoder; + public UserInfoDto getUserProfile(Long id){ + User user = userRepository.findById(id).orElse(null); + if (user == null){ + return null; + } + else { + return UserInfoDto.toDto(user); + } + } + @Override public ResponseEntity login(LoginRequestDTO loginRequestDTO) { //AccessToken 만들어서 줘야함 - Optional byEmail = memberRepository.findByEmail(loginRequestDTO.getEmail()); + Optional byEmail = userRepository.findByEmail(loginRequestDTO.getEmail()); if (byEmail.isEmpty()){ return new ResponseEntity<>(HttpStatus.NOT_FOUND); } else if (!passwordEncoder.matches(loginRequestDTO.getPassword(), byEmail.get().getPassword())) { @@ -47,9 +55,10 @@ public ResponseEntity signIn(MemberDTO memberDTO) { String encoded = passwordEncoder.encode(memberDTO.getPassword()); // 회원 저장 - MemberEntity saved = memberRepository.save(MemberEntity.builder() + User saved = userRepository.save(User.builder() + .name(memberDTO.getName()) .email(memberDTO.getEmail()) - .username(memberDTO.getUsername()) + .nickname(memberDTO.getNickName()) .password(encoded) .build()); @@ -57,12 +66,13 @@ public ResponseEntity signIn(MemberDTO memberDTO) { return new ResponseEntity<>("회원가입 완료", HttpStatus.OK); // 성공 시 200 반환 } catch (Exception e) { // 예외 발생 시 처리 + System.out.println("e = " + e); return new ResponseEntity<>("회원가입 실패", HttpStatus.BAD_REQUEST); // 이메일 조회 후 회원가입 할것 } } @Override - public ResponseEntity checkEmail(String email) { - return new ResponseEntity<>(memberRepository.findByEmail(email).isPresent(), HttpStatus.OK); + public ResponseEntity isEmailEmpty(String email) { + return new ResponseEntity<>(userRepository.findByEmail(email).isEmpty(), HttpStatus.OK); } } diff --git a/backend/src/main/java/com/itec0401/backend/member/controller/MemberController.java b/backend/src/main/java/com/itec0401/backend/member/controller/MemberController.java deleted file mode 100644 index 944e359..0000000 --- a/backend/src/main/java/com/itec0401/backend/member/controller/MemberController.java +++ /dev/null @@ -1,39 +0,0 @@ -package com.itec0401.backend.member.controller; - -import com.itec0401.backend.member.dto.LoginResponseDTO; -import com.itec0401.backend.member.dto.LoginRequestDTO; -import com.itec0401.backend.member.dto.MemberDTO; -import com.itec0401.backend.member.repository.MemberRepository; -import com.itec0401.backend.member.service.MemberService; -import lombok.RequiredArgsConstructor; -import org.springframework.http.ResponseEntity; -import org.springframework.web.bind.annotation.*; - -@RestController -@RequestMapping(value = "/member") -@RequiredArgsConstructor -public class MemberController { - - private final MemberService memberService; - private final MemberRepository memberRepository; - - /** - * @param loginRequestDTO - * @return AccessToken 반환 - */ - @PostMapping("/login") - public ResponseEntity login(@RequestBody LoginRequestDTO loginRequestDTO){ - return memberService.login(loginRequestDTO); - } - - @PostMapping("/new") - public ResponseEntity signIn(@RequestBody MemberDTO memberDTO){ - return memberService.signIn(memberDTO); - } - - //아이디 체크 - @GetMapping("/email/{email}") - public ResponseEntity checkEmail(@RequestParam String email){ - return memberService.checkEmail(email); - } -} diff --git a/backend/src/main/java/com/itec0401/backend/member/entity/MemberEntity.java b/backend/src/main/java/com/itec0401/backend/member/entity/MemberEntity.java deleted file mode 100644 index dedb85d..0000000 --- a/backend/src/main/java/com/itec0401/backend/member/entity/MemberEntity.java +++ /dev/null @@ -1,29 +0,0 @@ -package com.itec0401.backend.member.entity; - -import jakarta.persistence.*; -import lombok.AllArgsConstructor; -import lombok.Builder; -import lombok.Data; -import lombok.NoArgsConstructor; - -@Entity -@Data -@Builder -@AllArgsConstructor -@NoArgsConstructor -@Table(name = "MEMBER") -public class MemberEntity { - - @Id // 내가 PK - @GeneratedValue(strategy = GenerationType.IDENTITY) // 자동 id 생성 - private Long id; - - @Column(nullable = false, unique = true) - private String email; - - @Column - private String username; - - @Column(nullable = false) - private String password; -} diff --git a/backend/src/main/java/com/itec0401/backend/member/repository/MemberRepository.java b/backend/src/main/java/com/itec0401/backend/member/repository/MemberRepository.java deleted file mode 100644 index b350dff..0000000 --- a/backend/src/main/java/com/itec0401/backend/member/repository/MemberRepository.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.itec0401.backend.member.repository; - -import com.itec0401.backend.member.entity.MemberEntity; -import org.springframework.data.jpa.repository.JpaRepository; -import org.springframework.stereotype.Repository; - -import java.util.Optional; - -@Repository -public interface MemberRepository extends JpaRepository { - - Optional findByEmail(String email); - -} diff --git a/backend/src/main/java/com/itec0401/backend/member/service/MemberService.java b/backend/src/main/java/com/itec0401/backend/member/service/MemberService.java deleted file mode 100644 index 75578d9..0000000 --- a/backend/src/main/java/com/itec0401/backend/member/service/MemberService.java +++ /dev/null @@ -1,14 +0,0 @@ -package com.itec0401.backend.member.service; - -import com.itec0401.backend.member.dto.LoginRequestDTO; -import com.itec0401.backend.member.dto.LoginResponseDTO; -import com.itec0401.backend.member.dto.MemberDTO; -import org.springframework.http.ResponseEntity; - -public interface MemberService { - ResponseEntity login(LoginRequestDTO loginRequestDTO); - - ResponseEntity signIn(MemberDTO memberDTO); - - ResponseEntity checkEmail(String email); -} From ec3c4dae45aa2f7ad96f018e710ff4cca9e456be Mon Sep 17 00:00:00 2001 From: LeeDongjae Date: Sun, 13 Oct 2024 15:36:48 +0900 Subject: [PATCH 10/24] =?UTF-8?q?Docs:=20=ED=9A=8C=EC=9B=90=20=EA=B8=B0?= =?UTF-8?q?=EB=8A=A5=20api=20Swagger=20=EC=9E=91=EC=84=B1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../user/controller/UserController.java | 23 ++++++++++++++++++- .../domain/user/service/UserServiceImpl.java | 5 +++- 2 files changed, 26 insertions(+), 2 deletions(-) diff --git a/backend/src/main/java/com/itec0401/backend/domain/user/controller/UserController.java b/backend/src/main/java/com/itec0401/backend/domain/user/controller/UserController.java index 72c1645..fac08e5 100644 --- a/backend/src/main/java/com/itec0401/backend/domain/user/controller/UserController.java +++ b/backend/src/main/java/com/itec0401/backend/domain/user/controller/UserController.java @@ -3,6 +3,7 @@ import com.itec0401.backend.domain.user.dto.*; import com.itec0401.backend.domain.user.service.UserService; import io.swagger.v3.oas.annotations.Operation; +import io.swagger.v3.oas.annotations.responses.ApiResponse; import lombok.RequiredArgsConstructor; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @@ -25,17 +26,37 @@ public ResponseEntity updateUserProfile(@RequestParam Long user_id, return null; } + @Operation( + summary = "로그인", + description = "Email, Password를 확인하고 AccessToken 발행함.", + responses = { + @ApiResponse(responseCode = "200", description = "성공적으로 로그인 되었습니다."), + @ApiResponse(responseCode = "404", description = "이메일이 틀렸습니다."), + @ApiResponse(responseCode = "401", description = "비밀번호가 틀렸습니다.") + } + ) @PostMapping("/login") public ResponseEntity login(@RequestBody LoginRequestDTO loginRequestDTO){ return userService.login(loginRequestDTO); } + @Operation( + summary = "회원가입", + description = "Body에 회원정보(임시) 담아서 요청보내면 회원가입을 시켜줌. 이메일 중복 확인 후 호출해야함.", + responses = { + @ApiResponse(responseCode = "200", description = "성공적으로 회원가입 되었습니다."), + @ApiResponse(responseCode = "400", description = "회원가입 실패. 이메일 중복되었을 가능성 있음") + } + ) @PostMapping("/new") public ResponseEntity signIn(@RequestBody MemberDTO memberDTO){ return userService.signIn(memberDTO); } - //아이디 체크 + @Operation( + summary = "이메일 중복 확인", + description = "\"True: 회원가입 가능\" \"False: 회원가입 불가능\"" + ) @GetMapping("/email/{email}") public ResponseEntity isEmailEmpty(@PathVariable String email){ return userService.isEmailEmpty(email); diff --git a/backend/src/main/java/com/itec0401/backend/domain/user/service/UserServiceImpl.java b/backend/src/main/java/com/itec0401/backend/domain/user/service/UserServiceImpl.java index bfcc60d..07004df 100644 --- a/backend/src/main/java/com/itec0401/backend/domain/user/service/UserServiceImpl.java +++ b/backend/src/main/java/com/itec0401/backend/domain/user/service/UserServiceImpl.java @@ -8,6 +8,8 @@ import com.itec0401.backend.domain.user.jwt.JwtTokenProvider; import com.itec0401.backend.domain.user.repository.UserRepository; import lombok.RequiredArgsConstructor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.security.crypto.password.PasswordEncoder; @@ -18,6 +20,7 @@ @Service @RequiredArgsConstructor public class UserServiceImpl implements UserService{ + private static final Logger log = LoggerFactory.getLogger(UserServiceImpl.class); private final UserRepository userRepository; private final JwtTokenProvider jwtTokenProvider; private final PasswordEncoder passwordEncoder; @@ -66,7 +69,7 @@ public ResponseEntity signIn(MemberDTO memberDTO) { return new ResponseEntity<>("회원가입 완료", HttpStatus.OK); // 성공 시 200 반환 } catch (Exception e) { // 예외 발생 시 처리 - System.out.println("e = " + e); + log.info("회원가입 중 오류: " + e); return new ResponseEntity<>("회원가입 실패", HttpStatus.BAD_REQUEST); // 이메일 조회 후 회원가입 할것 } } From 6a75220acf145e865308eb65d90d555b0c8d3a38 Mon Sep 17 00:00:00 2001 From: milk-stone Date: Sun, 13 Oct 2024 19:01:36 +0900 Subject: [PATCH 11/24] feat: UserColor domain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UserService interface를 UserColorServiceImpl이 구현하도록 했음. --- .../domain/usercolor/entity/UserColor.java | 4 ++++ .../repository/UserColorRepository.java | 7 ++++++ .../usercolor/service/UserColorService.java | 8 +++++++ .../service/UserColorServiceImpl.java | 22 +++++++++++++++++++ 4 files changed, 41 insertions(+) create mode 100644 backend/src/main/java/com/itec0401/backend/domain/usercolor/repository/UserColorRepository.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/usercolor/service/UserColorService.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/usercolor/service/UserColorServiceImpl.java diff --git a/backend/src/main/java/com/itec0401/backend/domain/usercolor/entity/UserColor.java b/backend/src/main/java/com/itec0401/backend/domain/usercolor/entity/UserColor.java index 2632f64..831dce3 100644 --- a/backend/src/main/java/com/itec0401/backend/domain/usercolor/entity/UserColor.java +++ b/backend/src/main/java/com/itec0401/backend/domain/usercolor/entity/UserColor.java @@ -23,4 +23,8 @@ public class UserColor extends BaseEntityWithUpdatedAt { @JoinColumn(name = "color_id") private Color color; + public UserColor(User user, Color color) { + this.user = user; + this.color = color; + } } diff --git a/backend/src/main/java/com/itec0401/backend/domain/usercolor/repository/UserColorRepository.java b/backend/src/main/java/com/itec0401/backend/domain/usercolor/repository/UserColorRepository.java new file mode 100644 index 0000000..388194b --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/usercolor/repository/UserColorRepository.java @@ -0,0 +1,7 @@ +package com.itec0401.backend.domain.usercolor.repository; + +import com.itec0401.backend.domain.usercolor.entity.UserColor; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserColorRepository extends JpaRepository { +} diff --git a/backend/src/main/java/com/itec0401/backend/domain/usercolor/service/UserColorService.java b/backend/src/main/java/com/itec0401/backend/domain/usercolor/service/UserColorService.java new file mode 100644 index 0000000..55b3788 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/usercolor/service/UserColorService.java @@ -0,0 +1,8 @@ +package com.itec0401.backend.domain.usercolor.service; + +import com.itec0401.backend.domain.color.entity.Color; +import com.itec0401.backend.domain.user.entity.User; + +public interface UserColorService { + void createUserColor(User user, Color color); +} diff --git a/backend/src/main/java/com/itec0401/backend/domain/usercolor/service/UserColorServiceImpl.java b/backend/src/main/java/com/itec0401/backend/domain/usercolor/service/UserColorServiceImpl.java new file mode 100644 index 0000000..8812fd7 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/usercolor/service/UserColorServiceImpl.java @@ -0,0 +1,22 @@ +package com.itec0401.backend.domain.usercolor.service; + +import com.itec0401.backend.domain.color.entity.Color; +import com.itec0401.backend.domain.color.service.ColorService; +import com.itec0401.backend.domain.user.entity.User; +import com.itec0401.backend.domain.usercolor.entity.UserColor; +import com.itec0401.backend.domain.usercolor.repository.UserColorRepository; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class UserColorServiceImpl implements UserColorService { + private final UserColorRepository userColorRepository; + private final ColorService colorService; + + @Transactional + public void createUserColor(User user, Color color) { + userColorRepository.save(new UserColor(user, color)); + } +} From dbbefea6fc7f29cb759053e1a4dc7770f1891429 Mon Sep 17 00:00:00 2001 From: milk-stone Date: Sun, 13 Oct 2024 19:02:29 +0900 Subject: [PATCH 12/24] feat: UserStyle domain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit UserStyleService interface를 UserStyleServiceImpl이 구현하도록 했음. --- .../domain/userstyle/entity/UserStyle.java | 4 ++++ .../repository/UserStyleRepository.java | 7 ++++++ .../userstyle/service/UserStyleService.java | 8 +++++++ .../service/UserStyleServiceImpl.java | 24 +++++++++++++++++++ 4 files changed, 43 insertions(+) create mode 100644 backend/src/main/java/com/itec0401/backend/domain/userstyle/repository/UserStyleRepository.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/userstyle/service/UserStyleService.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/userstyle/service/UserStyleServiceImpl.java diff --git a/backend/src/main/java/com/itec0401/backend/domain/userstyle/entity/UserStyle.java b/backend/src/main/java/com/itec0401/backend/domain/userstyle/entity/UserStyle.java index 97b722d..330214e 100644 --- a/backend/src/main/java/com/itec0401/backend/domain/userstyle/entity/UserStyle.java +++ b/backend/src/main/java/com/itec0401/backend/domain/userstyle/entity/UserStyle.java @@ -22,4 +22,8 @@ public class UserStyle { @JoinColumn(name = "style_id") private Style style; + public UserStyle(User user, Style style) { + this.user = user; + this.style = style; + } } diff --git a/backend/src/main/java/com/itec0401/backend/domain/userstyle/repository/UserStyleRepository.java b/backend/src/main/java/com/itec0401/backend/domain/userstyle/repository/UserStyleRepository.java new file mode 100644 index 0000000..2909010 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/userstyle/repository/UserStyleRepository.java @@ -0,0 +1,7 @@ +package com.itec0401.backend.domain.userstyle.repository; + +import com.itec0401.backend.domain.userstyle.entity.UserStyle; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface UserStyleRepository extends JpaRepository { +} diff --git a/backend/src/main/java/com/itec0401/backend/domain/userstyle/service/UserStyleService.java b/backend/src/main/java/com/itec0401/backend/domain/userstyle/service/UserStyleService.java new file mode 100644 index 0000000..2f24a72 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/userstyle/service/UserStyleService.java @@ -0,0 +1,8 @@ +package com.itec0401.backend.domain.userstyle.service; + +import com.itec0401.backend.domain.style.entity.Style; +import com.itec0401.backend.domain.user.entity.User; + +public interface UserStyleService { + void createUserStyle(User user, Style style); +} diff --git a/backend/src/main/java/com/itec0401/backend/domain/userstyle/service/UserStyleServiceImpl.java b/backend/src/main/java/com/itec0401/backend/domain/userstyle/service/UserStyleServiceImpl.java new file mode 100644 index 0000000..6bbf37f --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/userstyle/service/UserStyleServiceImpl.java @@ -0,0 +1,24 @@ +package com.itec0401.backend.domain.userstyle.service; + +import com.itec0401.backend.domain.style.entity.Style; +import com.itec0401.backend.domain.style.service.StyleService; +import com.itec0401.backend.domain.user.entity.User; +import com.itec0401.backend.domain.userstyle.entity.UserStyle; +import com.itec0401.backend.domain.userstyle.repository.UserStyleRepository; +import jakarta.transaction.Transactional; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +@Service +@RequiredArgsConstructor +public class UserStyleServiceImpl implements UserStyleService { + private final UserStyleRepository userStyleRepository; + private final StyleService styleService; + + @Transactional + public void createUserStyle(User user, Style style) { + userStyleRepository.save(new UserStyle(user, style)); + + } + +} From 61d73658af56858754d4ed3b0f76b9f70799c595 Mon Sep 17 00:00:00 2001 From: milk-stone Date: Sun, 13 Oct 2024 19:03:25 +0900 Subject: [PATCH 13/24] feat: Style, Color domain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit StyleService interface를 StyleServiceImpl이 구현하도록 했음. --- .../backend/domain/color/entity/Color.java | 6 ++++++ .../color/repository/ColorRepository.java | 10 +++++++++ .../domain/color/service/ColorService.java | 13 ++++++++++++ .../color/service/ColorServiceImpl.java | 21 +++++++++++++++++++ .../backend/domain/style/entity/Style.java | 6 ++++++ .../style/repository/StyleRepository.java | 10 +++++++++ .../domain/style/service/StyleService.java | 9 ++++++++ .../style/service/StyleServiceImpl.java | 21 +++++++++++++++++++ 8 files changed, 96 insertions(+) create mode 100644 backend/src/main/java/com/itec0401/backend/domain/color/repository/ColorRepository.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/color/service/ColorService.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/color/service/ColorServiceImpl.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/style/repository/StyleRepository.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/style/service/StyleService.java create mode 100644 backend/src/main/java/com/itec0401/backend/domain/style/service/StyleServiceImpl.java diff --git a/backend/src/main/java/com/itec0401/backend/domain/color/entity/Color.java b/backend/src/main/java/com/itec0401/backend/domain/color/entity/Color.java index 3cac0df..9d21305 100644 --- a/backend/src/main/java/com/itec0401/backend/domain/color/entity/Color.java +++ b/backend/src/main/java/com/itec0401/backend/domain/color/entity/Color.java @@ -3,6 +3,7 @@ import com.itec0401.backend.domain.usercolor.entity.UserColor; import com.itec0401.backend.global.BaseEntity; import jakarta.persistence.*; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -20,4 +21,9 @@ public class Color extends BaseEntity { @OneToMany(mappedBy = "color") private List userColors; + + @Builder + public Color(String color) { + this.color = color; + } } diff --git a/backend/src/main/java/com/itec0401/backend/domain/color/repository/ColorRepository.java b/backend/src/main/java/com/itec0401/backend/domain/color/repository/ColorRepository.java new file mode 100644 index 0000000..fc0081c --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/color/repository/ColorRepository.java @@ -0,0 +1,10 @@ +package com.itec0401.backend.domain.color.repository; + +import com.itec0401.backend.domain.color.entity.Color; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface ColorRepository extends JpaRepository { + Optional findByColor(String color); +} diff --git a/backend/src/main/java/com/itec0401/backend/domain/color/service/ColorService.java b/backend/src/main/java/com/itec0401/backend/domain/color/service/ColorService.java new file mode 100644 index 0000000..6992f01 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/color/service/ColorService.java @@ -0,0 +1,13 @@ +package com.itec0401.backend.domain.color.service; + +import com.itec0401.backend.domain.color.entity.Color; +import com.itec0401.backend.domain.color.repository.ColorRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Optional; + + +public interface ColorService { + Optional findColorByName(String color); +} diff --git a/backend/src/main/java/com/itec0401/backend/domain/color/service/ColorServiceImpl.java b/backend/src/main/java/com/itec0401/backend/domain/color/service/ColorServiceImpl.java new file mode 100644 index 0000000..52c0066 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/color/service/ColorServiceImpl.java @@ -0,0 +1,21 @@ +package com.itec0401.backend.domain.color.service; + +import com.itec0401.backend.domain.color.entity.Color; +import com.itec0401.backend.domain.color.repository.ColorRepository; +import lombok.RequiredArgsConstructor; +import org.springframework.stereotype.Service; + +import java.util.Optional; + +@Service +@RequiredArgsConstructor +public class ColorServiceImpl implements ColorService { + private final ColorRepository colorRepository; + + // Color 이름으로 color 객체 찾기 + public Optional findColorByName(String color) { + return colorRepository.findByColor(color); + } + + // Color 초기 값 생성은 관리자가 DB에 직접 넣기! +} diff --git a/backend/src/main/java/com/itec0401/backend/domain/style/entity/Style.java b/backend/src/main/java/com/itec0401/backend/domain/style/entity/Style.java index 2b1c21b..4464200 100644 --- a/backend/src/main/java/com/itec0401/backend/domain/style/entity/Style.java +++ b/backend/src/main/java/com/itec0401/backend/domain/style/entity/Style.java @@ -2,6 +2,7 @@ import com.itec0401.backend.domain.userstyle.entity.UserStyle; import jakarta.persistence.*; +import lombok.Builder; import lombok.Getter; import lombok.NoArgsConstructor; @@ -19,4 +20,9 @@ public class Style { @OneToMany(mappedBy = "style") private List userStyles; + + @Builder + public Style(String style){ + this.style = style; + } } diff --git a/backend/src/main/java/com/itec0401/backend/domain/style/repository/StyleRepository.java b/backend/src/main/java/com/itec0401/backend/domain/style/repository/StyleRepository.java new file mode 100644 index 0000000..84bd772 --- /dev/null +++ b/backend/src/main/java/com/itec0401/backend/domain/style/repository/StyleRepository.java @@ -0,0 +1,10 @@ +package com.itec0401.backend.domain.style.repository; + +import com.itec0401.backend.domain.style.entity.Style; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.Optional; + +public interface StyleRepository extends JpaRepository { + Optional