diff --git a/core/core-api/src/main/java/com/nerd/favorite18/core/api/auth/business/AuthBusiness.java b/core/core-api/src/main/java/com/nerd/favorite18/core/api/auth/business/AuthBusiness.java
index 949eb3c..7f6bd5f 100644
--- a/core/core-api/src/main/java/com/nerd/favorite18/core/api/auth/business/AuthBusiness.java
+++ b/core/core-api/src/main/java/com/nerd/favorite18/core/api/auth/business/AuthBusiness.java
@@ -2,9 +2,12 @@
import com.nerd.favorite18.core.api._common.annotation.Business;
import com.nerd.favorite18.core.api._common.client.OAuth2Client;
+import com.nerd.favorite18.core.api._common.support.error.CoreApiException;
+import com.nerd.favorite18.core.api._common.support.error.ErrorType;
import com.nerd.favorite18.core.api._common.utils.SHA256HashUtils;
import com.nerd.favorite18.core.api.auth.dto.request.AuthLoginGoogleRequest;
import com.nerd.favorite18.core.api.auth.dto.request.AuthRefreshRequest;
+import com.nerd.favorite18.core.api.auth.dto.request.AuthSignupGoogleRequest;
import com.nerd.favorite18.core.api.auth.dto.response.AuthGoogleAccessTokenResponse;
import com.nerd.favorite18.core.api.auth.model.GoogleUserInfo;
import com.nerd.favorite18.core.api.auth.model.GoogleUserInfoMobile;
@@ -29,14 +32,52 @@ public class AuthBusiness {
private final OAuth2Client oauth2Client;
/**
- * [ 로그인 요청 ]
+ * [ 회원가입 ]
*
- * 1. 구글 OAuth2.0 로그인 요청 클라이언트 실행
+ * 1. OAuth2.0 로그인 진행 후 리다이렉트 되어 실행되는 로직
*
- * @return Redirect URI
+ * @param request 생년월일, 성별, 사용자 정보
+ * @return 사용자 정보
*/
- public URI login() {
- return oauth2Client.getAuthorizationUri();
+ public UserDto signUp(AuthSignupGoogleRequest request) {
+ GoogleUserInfoMobile googleUserInfo = new GoogleUserInfoMobile(request.getUserInfo());
+
+ return userService.saveUser(
+ UserRegisterRequest.of(
+ googleUserInfo.getSubId(),
+ googleUserInfo.getEmail(),
+ googleUserInfo.getName(),
+ request.getBirth(),
+ request.getGender(),
+ googleUserInfo.getThumbnail()
+ )
+ );
+ }
+
+ /**
+ * [ 로그인 체크 With Error ]
+ *
+ * 1. 구글 유저정보 기반으로 DB 에서 유저 조회
+ * 2. 유저 없으면 400 에러 반환
+ * 3. 유저 있으면 바로 유저 조회 결과 반환
+ * 4. 반환된 유저정보 기준으로 Jwt 토큰 발행
+ *
+ * @param userInfo OAuth 유저정보
+ * @return JwtResponse JWT 토큰 발행
+ */
+ private JwtResponse checkLoginUserWithError(OAuth2UserInfo userInfo) {
+ UserDto userDto;
+ try {
+ // 유저 조회하고 있으면 바로 반환, 만약 유저 상태가 ACTIVE 가 아니면 ACTIVE 로 바꾸고 사용자 반환
+ userDto = userService.getUserAndUpdateStatusWithThrow(userInfo.getSubId(), userInfo.getEmail());
+ } catch (RuntimeException e) {
+ throw new CoreApiException(ErrorType.USER_NOT_FOUND, "회원가입이 되어있지 않습니다.");
+ }
+
+ final JwtResponse jwtResponse = jwtBusiness.issueToken(userDto);
+ userService.updateUserRefreshToken(userDto.getId(), SHA256HashUtils.hashToken(jwtResponse.getRefreshToken()));
+
+ return jwtResponse;
}
/**
@@ -50,27 +91,18 @@ public URI login() {
public JwtResponse loginGoogle(AuthLoginGoogleRequest request) {
GoogleUserInfoMobile googleUserInfo = new GoogleUserInfoMobile(request.getUserInfo());
- return checkLoginUser(googleUserInfo);
+ return checkLoginUserWithError(googleUserInfo);
}
/**
- * [ 웹 콜백 로그인 ]
+ * [ 로그인 요청 ]
*
- * 1. OAuth2.0 로그인 진행 후 리다이렉트 되어 실행되는 로직
- * 2. 구글 API 에서 AccessToken 받음
- * 3. 전달받은 AccessToken 으로 유저정보 API 실행
- * 4. 유저정보로 유저 체크 후 JWT 토큰 발행
+ * 1. 구글 OAuth2.0 로그인 요청 클라이언트 실행
*
- * @param authorizationCode 구글로 부터 전달받은 인증코드
- * @return JwtResponse JWT 토큰 발행
+ * @return Redirect URI
*/
- public JwtResponse callbackGoogle(String authorizationCode) {
- AuthGoogleAccessTokenResponse tokenResponse = oauth2Client.getAccessToken(authorizationCode);
-
- String accessToken = tokenResponse.getAccessToken();
- GoogleUserInfo googleUserInfo = new GoogleUserInfo(oauth2Client.getUserInfo(accessToken));
-
- return checkLoginUser(googleUserInfo);
+ public URI login() {
+ return oauth2Client.getAuthorizationUri();
}
/**
@@ -92,7 +124,12 @@ private JwtResponse checkLoginUser(OAuth2UserInfo userInfo) {
} catch (RuntimeException e) {
// 조회되지 않으면 강제 회원가입 후 유저 반환
userDto = userService.saveUser(UserRegisterRequest.of(
- userInfo.getSubId(), userInfo.getEmail(), userInfo.getName(), userInfo.getThumbnail())
+ userInfo.getSubId(),
+ userInfo.getEmail(),
+ userInfo.getName(),
+ null,
+ null,
+ userInfo.getThumbnail())
);
}
@@ -102,6 +139,26 @@ private JwtResponse checkLoginUser(OAuth2UserInfo userInfo) {
return jwtResponse;
}
+ /**
+ * [ 웹 콜백 로그인 ]
+ *
+ * 1. OAuth2.0 로그인 진행 후 리다이렉트 되어 실행되는 로직
+ * 2. 구글 API 에서 AccessToken 받음
+ * 3. 전달받은 AccessToken 으로 유저정보 API 실행
+ * 4. 유저정보로 유저 체크 후 JWT 토큰 발행
+ *
+ * @param authorizationCode 구글로 부터 전달받은 인증코드
+ * @return JwtResponse JWT 토큰 발행
+ */
+ public JwtResponse callbackGoogle(String authorizationCode) {
+ AuthGoogleAccessTokenResponse tokenResponse = oauth2Client.getAccessToken(authorizationCode);
+
+ String accessToken = tokenResponse.getAccessToken();
+ GoogleUserInfo googleUserInfo = new GoogleUserInfo(oauth2Client.getUserInfo(accessToken));
+
+ return checkLoginUser(googleUserInfo);
+ }
+
/**
* [ 리프레쉬 토큰 발행 ]
*
diff --git a/core/core-api/src/main/java/com/nerd/favorite18/core/api/auth/controller/AuthOpenApiController.java b/core/core-api/src/main/java/com/nerd/favorite18/core/api/auth/controller/AuthOpenApiController.java
index d7e4a89..953329c 100644
--- a/core/core-api/src/main/java/com/nerd/favorite18/core/api/auth/controller/AuthOpenApiController.java
+++ b/core/core-api/src/main/java/com/nerd/favorite18/core/api/auth/controller/AuthOpenApiController.java
@@ -1,9 +1,11 @@
package com.nerd.favorite18.core.api.auth.controller;
+import com.nerd.favorite18.core.api._common.support.response.ApiResponse;
import com.nerd.favorite18.core.api.auth.business.AuthBusiness;
import com.nerd.favorite18.core.api.auth.dto.request.AuthLoginGoogleRequest;
+import com.nerd.favorite18.core.api.auth.dto.request.AuthSignupGoogleRequest;
import com.nerd.favorite18.core.api.jwt.dto.JwtResponse;
-import com.nerd.favorite18.core.api._common.support.response.ApiResponse;
+import com.nerd.favorite18.core.api.user.dto.UserDto;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.GetMapping;
@@ -22,11 +24,12 @@
public class AuthOpenApiController {
private final AuthBusiness authBusiness;
- // 로그인 url 발행 요청
- @GetMapping("/login")
- public URI login() {
+ // 모바일 회원가입 진행
+ @PostMapping("/signup")
+ public ApiResponse signUp(@RequestBody AuthSignupGoogleRequest request) {
+ final UserDto userDto = authBusiness.signUp(request);
- return authBusiness.login();
+ return ApiResponse.success(userDto);
}
// 모바일 로그인 진행
@@ -37,6 +40,13 @@ public ApiResponse loginGoogle(@RequestBody AuthLoginGoogleRequest
return ApiResponse.success(jwtResponse);
}
+ // 로그인 url 발행 요청
+ @GetMapping("/login")
+ public URI login() {
+
+ return authBusiness.login();
+ }
+
// 웹 로그인 콜백 주소
@GetMapping("/login/oauth2/code/google")
public ApiResponse callbackGoogle(@RequestParam("code") String authorizationCode) {
diff --git a/core/core-api/src/main/java/com/nerd/favorite18/core/api/auth/dto/request/AuthSignupGoogleRequest.java b/core/core-api/src/main/java/com/nerd/favorite18/core/api/auth/dto/request/AuthSignupGoogleRequest.java
new file mode 100644
index 0000000..ec1f3c0
--- /dev/null
+++ b/core/core-api/src/main/java/com/nerd/favorite18/core/api/auth/dto/request/AuthSignupGoogleRequest.java
@@ -0,0 +1,12 @@
+package com.nerd.favorite18.core.api.auth.dto.request;
+
+import com.nerd.favorite18.core.api.auth.model.UserInfo;
+import com.nerd.favorite18.core.enums.user.UserGender;
+import lombok.Getter;
+
+@Getter
+public class AuthSignupGoogleRequest {
+ String birth;
+ UserGender gender;
+ UserInfo userInfo;
+}
diff --git a/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/business/UserBusiness.java b/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/business/UserBusiness.java
index 219286f..78e5079 100644
--- a/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/business/UserBusiness.java
+++ b/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/business/UserBusiness.java
@@ -17,8 +17,8 @@ public class UserBusiness {
* @param user 로그인 유저 정보
* @param request 업데이트할 이름
*/
- public void updateNickname(UserDto user, UserUpdateNicknameRequest request) {
- userService.updateNickname(user, request);
+ public UserDto updateNickname(UserDto user, UserUpdateNicknameRequest request) {
+ return userService.updateNickname(user, request);
}
/**
diff --git a/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/controller/UserController.java b/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/controller/UserController.java
index dba00e8..910323f 100644
--- a/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/controller/UserController.java
+++ b/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/controller/UserController.java
@@ -23,10 +23,10 @@ public ApiResponse me(@UserSession UserDto user) {
// 사용자 닉네임 변경
@PutMapping("/nickname")
- public ApiResponse updateNickname(@UserSession UserDto user, @RequestBody UserUpdateNicknameRequest request) {
- userBusiness.updateNickname(user, request);
+ public ApiResponse updateNickname(@UserSession UserDto user, @RequestBody UserUpdateNicknameRequest request) {
+ final UserDto userDto = userBusiness.updateNickname(user, request);
- return ApiResponse.success();
+ return ApiResponse.success(userDto);
}
// 회원 탈퇴
diff --git a/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/converter/UserConverter.java b/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/converter/UserConverter.java
index 5f11b3d..d5179d1 100644
--- a/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/converter/UserConverter.java
+++ b/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/converter/UserConverter.java
@@ -17,6 +17,8 @@ public User toEntity(UserRegisterRequest request) {
.subId(request.getSubId())
.email(request.getEmail())
.name(request.getName())
+ .birth(request.getBirth())
+ .gender(request.getGender())
.thumbnail(request.getThumbnail())
.role(UserRole.USER)
.status(UserStatus.ACTIVE)
@@ -42,4 +44,23 @@ public UserDto toDto(User entity) {
entity.getUpdatedAt()
);
}
+
+ public UserDto toDtoWithoutToken(User entity) {
+
+ return UserDto.of(
+ entity.getId(),
+ entity.getSubId(),
+ entity.getEmail(),
+ entity.getName(),
+ entity.getNickname(),
+ entity.getBirth(),
+ entity.getGender(),
+ entity.getThumbnail(),
+ entity.getRole(),
+ entity.getStatus(),
+ null,
+ entity.getCreatedAt(),
+ entity.getUpdatedAt()
+ );
+ }
}
diff --git a/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/dto/request/UserRegisterRequest.java b/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/dto/request/UserRegisterRequest.java
index 273a48c..154477f 100644
--- a/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/dto/request/UserRegisterRequest.java
+++ b/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/dto/request/UserRegisterRequest.java
@@ -1,13 +1,12 @@
package com.nerd.favorite18.core.api.user.dto.request;
+import com.nerd.favorite18.core.enums.user.UserGender;
import jakarta.validation.constraints.Email;
import jakarta.validation.constraints.NotBlank;
import lombok.AllArgsConstructor;
-import lombok.Data;
-import lombok.NoArgsConstructor;
+import lombok.Getter;
-@Data
-@NoArgsConstructor
+@Getter
@AllArgsConstructor
public class UserRegisterRequest {
@NotBlank
@@ -18,10 +17,19 @@ public class UserRegisterRequest {
private String email;
private String name;
+ private String birth;
+ private UserGender gender;
private String thumbnail;
- public static UserRegisterRequest of(String subId, String email, String name, String thumbnail) {
- return new UserRegisterRequest(subId, email, name, thumbnail);
+ public static UserRegisterRequest of(
+ String subId,
+ String email,
+ String name,
+ String birth,
+ UserGender gender,
+ String thumbnail
+ ) {
+ return new UserRegisterRequest(subId, email, name, birth, gender, thumbnail);
}
}
diff --git a/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/service/UserService.java b/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/service/UserService.java
index 0c57f58..c6031d1 100644
--- a/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/service/UserService.java
+++ b/core/core-api/src/main/java/com/nerd/favorite18/core/api/user/service/UserService.java
@@ -89,15 +89,16 @@ public UserDto saveUser(UserRegisterRequest request) {
*
* @param user 로그인 사용자 정보
* @param request 변경할 닉네임
+ * @return 사용자 정보
*/
@Transactional
- public void updateNickname(UserDto user, UserUpdateNicknameRequest request) {
+ public UserDto updateNickname(UserDto user, UserUpdateNicknameRequest request) {
User userEntity = userRepository.findFirstByIdAndStatusOrderByIdDesc(user.getId(), UserStatus.ACTIVE)
.orElseThrow(() -> new CoreApiException(ErrorType.USER_NOT_FOUND));
userEntity.updateNickname(request.getNickname());
- userRepository.save(userEntity);
+ return userConverter.toDtoWithoutToken(userRepository.save(userEntity));
}
/**
diff --git a/storage/db-core/src/main/java/com/nerd/favorite18/storage/db/core/user/entity/User.java b/storage/db-core/src/main/java/com/nerd/favorite18/storage/db/core/user/entity/User.java
index b8ecb9a..0c7d455 100644
--- a/storage/db-core/src/main/java/com/nerd/favorite18/storage/db/core/user/entity/User.java
+++ b/storage/db-core/src/main/java/com/nerd/favorite18/storage/db/core/user/entity/User.java
@@ -23,11 +23,11 @@
@NoArgsConstructor(access = AccessLevel.PROTECTED)
public class User extends BaseEntity {
@Comment("사용자 ID : provider_sub")
- @Column(length = 100, nullable = false)
+ @Column(unique = true, length = 100, nullable = false)
private String subId;
@Comment("사용자 이메일")
- @Column(length = 50, nullable = false)
+ @Column(unique = true, length = 50, nullable = false)
private String email;
@Comment("사용자 이름")