Skip to content

Commit

Permalink
Merge pull request #55 from OnAndOff-UMC/feat/#54
Browse files Browse the repository at this point in the history
[feat]: 회원가입 로직 수정
  • Loading branch information
wu-seong authored Feb 4, 2024
2 parents 953cc27 + 6fb0d3d commit d5d233c
Show file tree
Hide file tree
Showing 13 changed files with 173 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public enum ErrorStatus implements BaseErrorCode {
// 로그인 관련 에러
INVALID_TOKEN_ERROR(HttpStatus.UNAUTHORIZED, "LOGIN4001", "토큰값이 잘못되었거나 유효하지 않습니다."),
INVALID_ARGUMENT_ERROR(HttpStatus.BAD_REQUEST, "LOGIN4002", "필수인자가 포함되지 않거나 인자값의 데이터 타입 또는 범위가 적절하지 않습니다."),
INVALID_ENUM_VALUE(HttpStatus.BAD_REQUEST, "LOGIN4003", "추가로 입력한 업무분야나 연차의 형식이 올바르지 않습니다."),
TEMPORARY_INTERNAL_SERVER_ERROR(HttpStatus.INTERNAL_SERVER_ERROR , "LOGIN5000", "카카오 플랫폼 서비스의 일시적 내부 장애입니다. 잠시후에 다시 시도해주세요");


Expand Down
3 changes: 2 additions & 1 deletion src/main/java/com/onnoff/onnoff/auth/config/WebConfig.java
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ public void addInterceptors(InterceptorRegistry registry) {

registry.addInterceptor(new UserInterceptor(userService, jwtUtil))
.addPathPatterns("/**") // 스프링 경로는 /*와 /**이 다름
.excludePathPatterns("/swagger-ui/**", "/v3/api-docs/**", "/oauth2/**", "/health", "/token/**" , "/message/**");
.excludePathPatterns("/swagger-ui/**", "/v3/api-docs/**", "/oauth2/**", "/health", "/token/**" ,
"/message/**", "/enums/**");
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ public ResponseEntity<String> getAccessToken(@RequestParam(name = "code") String
@Operation(summary = "소셜 토큰 검증 API",description = "토큰을 검증 하고 이에 대한 결과를 응답합니다. 추가 정보 입력 여부도 같이 응답 합니다.")
@ResponseBody
@PostMapping("/oauth2/kakao/token/validate")
public ApiResponse<UserResponseDTO.LoginDTO> validateKakoToken(HttpServletResponse response, @RequestBody LoginRequestDTO.KakaoTokenValidateDTO requestDTO) {
public ApiResponse<UserResponseDTO.LoginDTO> validateKakoToken(@RequestBody LoginRequestDTO.KakaoTokenValidateDTO requestDTO) {
// identity 토큰 검증
kakaoLoginService.validate(requestDTO.getIdentityToken());
// ok -> 유저 정보 가져오기
Expand All @@ -98,17 +98,17 @@ public ApiResponse<UserResponseDTO.LoginDTO> validateKakoToken(HttpServletRespon
user = userService.getUserByOauthId(oauthId);
}
else{
user = UserConverter.toUser(userInfo);
user = UserConverter.toUser(userInfo, requestDTO.getAdditionalInfo());
user = userService.create(user);
}
// 응답본문에 토큰 추가
JwtToken token = jwtUtil.generateToken(String.valueOf(user.getId()));
return ApiResponse.onSuccess(UserConverter.toLoginDTO(user, token.getAccessToken(), token.getRefreshToken()));
return ApiResponse.onSuccess(UserConverter.toLoginDTO(token.getAccessToken(), token.getRefreshToken()));
}

@ResponseBody
@PostMapping("/oauth2/apple/token/validate")
public ApiResponse<UserResponseDTO.LoginDTO> validateAppleToken(HttpServletResponse response, @RequestBody LoginRequestDTO.AppleTokenValidateDTO requestDTO) {
public ApiResponse<UserResponseDTO.LoginDTO> validateAppleToken(@RequestBody LoginRequestDTO.AppleTokenValidateDTO requestDTO) {
// 검증하기
appleLoginService.validate(requestDTO.getIdentityToken());
// 검증 성공 시 리프레시 토큰 발급받아 저장(기한 무제한, 회원탈퇴 시 필요)
Expand All @@ -120,17 +120,17 @@ public ApiResponse<UserResponseDTO.LoginDTO> validateAppleToken(HttpServletRespo
user = userService.getUserByOauthId(oauthId);
}
else{
user = UserConverter.toUser(requestDTO);
user = UserConverter.toUser(requestDTO, requestDTO.getAdditionalInfo());
user.setAppleRefreshToken(tokenResponse.getRefreshToken());
user = userService.create(user);
}
// 응답헤더에 토큰 추가
JwtToken token = jwtUtil.generateToken(String.valueOf(user.getId()));
return ApiResponse.onSuccess(UserConverter.toLoginDTO(user, token.getAccessToken(), token.getRefreshToken()));
return ApiResponse.onSuccess(UserConverter.toLoginDTO(token.getAccessToken(), token.getRefreshToken()));
}

@Operation(summary = "서버 토큰 검증 API",description = "토큰의 유효성을 검증하고 액세스 토큰이 만료되었으면" +
"재발급, 리프레시 토큰까지 만료되었으면 오류 응답 추가. 정보 입력 여부도 같이 응답 합니다.")
"재발급, 리프레시 토큰까지 만료되었으면 4001 오류 응답")
@ResponseBody
@PostMapping("/token/validate")
public ApiResponse<UserResponseDTO.LoginDTO> validateServerToken(@RequestBody JwtToken tokenDTO){
Expand All @@ -140,7 +140,7 @@ public ApiResponse<UserResponseDTO.LoginDTO> validateServerToken(@RequestBody Jw
// accessToken 유효
String userId = jwtUtil.getUserId(accessToken);
User user = userService.getUser(Long.valueOf(userId));
UserResponseDTO.LoginDTO loginDTO = UserConverter.toLoginDTO(user, accessToken, refreshToken);
UserResponseDTO.LoginDTO loginDTO = UserConverter.toLoginDTO(accessToken, refreshToken);
return ApiResponse.onSuccess(loginDTO);
}
if (jwtTokenProvider.verifyToken(refreshToken)) {
Expand All @@ -150,7 +150,7 @@ public ApiResponse<UserResponseDTO.LoginDTO> validateServerToken(@RequestBody Jw

String newRefreshToken = jwtUtil.generateRefreshToken(jwtUtil.getUserId(refreshToken));
String newAccessToken = jwtUtil.generateAccessToken(jwtUtil.getUserId(refreshToken));
return ApiResponse.onSuccess(UserConverter.toLoginDTO(user, newAccessToken, newRefreshToken));
return ApiResponse.onSuccess(UserConverter.toLoginDTO(newAccessToken, newRefreshToken));
}
// 둘 다 유효하지 않은 경우
throw new GeneralException(ErrorStatus.INVALID_TOKEN_ERROR);
Expand Down
16 changes: 15 additions & 1 deletion src/main/java/com/onnoff/onnoff/auth/dto/LoginRequestDTO.java
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,28 @@ public class LoginRequestDTO {
@Getter
public static class AppleTokenValidateDTO{
private String oauthId;
private String fullName;
private Fullname fullName;
private String email;
private String identityToken;
private String authorizationCode;
private AdditionalInfo additionalInfo;
}
@Getter
public static class KakaoTokenValidateDTO{
private String identityToken;
private String accessToken;
private AdditionalInfo additionalInfo;
}

@Getter
public static class AdditionalInfo{
private String fieldOfWork;
private String job;
private String experienceYear;
}
@Getter
public static class Fullname{
private String givenName;
private String familyName;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
@RequiredArgsConstructor
public class JwtAuthFilter extends OncePerRequestFilter {
private final JwtTokenProvider jwtTokenProvider;
private final static String[] ignorePrefix = {"/swagger-ui", "/v3/api-docs", "/oauth2", "/health", "/token/validate" , "/message"};
private final static String[] ignorePrefix = {"/swagger-ui", "/v3/api-docs", "/oauth2", "/health", "/token/validate" , "/message", "/enums"};
@Override
protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
log.info("url ={}", request.getRequestURI());
Expand Down
9 changes: 6 additions & 3 deletions src/main/java/com/onnoff/onnoff/domain/user/User.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import com.onnoff.onnoff.domain.off.memoir.entity.Memoir;
import com.onnoff.onnoff.domain.on.resolution.entity.Resolution;
import com.onnoff.onnoff.domain.on.worklog.entity.Worklog;
import com.onnoff.onnoff.domain.user.enums.ExperienceYear;
import com.onnoff.onnoff.domain.user.enums.FieldOfWork;
import com.onnoff.onnoff.domain.user.enums.SocialType;
import com.onnoff.onnoff.domain.user.enums.Status;
import jakarta.persistence.*;
Expand Down Expand Up @@ -46,15 +48,16 @@ public class User extends BaseEntity {
@Column(nullable = false)
private String email;

@Column(length = 30)
private String fieldOfWork;
@Enumerated(EnumType.STRING)
private FieldOfWork fieldOfWork;

// private String profile_image;
@Column(length = 30)
private String job;

@Column(length = 30)
private String experienceYear;
@Enumerated(EnumType.STRING)
private ExperienceYear experienceYear;

@Column(columnDefinition = "VARCHAR(10) DEFAULT 'ACTIVE'")
@Enumerated(EnumType.STRING)
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package com.onnoff.onnoff.domain.user.controller;

import com.onnoff.onnoff.apiPayload.ApiResponse;
import com.onnoff.onnoff.domain.user.dto.EnumInquiryResponseDTO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
@RequestMapping("/enums")
public class InquiryEnumController {
@GetMapping("/field-of-works")
public ApiResponse<List<String>> getAllFieldValues(){
return ApiResponse.onSuccess(EnumInquiryResponseDTO.FieldOfWorkResponseDTO.getAllField());
}
@GetMapping("/experience-years")
public ApiResponse<List<String>> getAllExperienceValues(){
return ApiResponse.onSuccess(EnumInquiryResponseDTO.ExperienceYearResponseDTO.getAllExperience());
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.onnoff.onnoff.domain.user.controller;


import com.onnoff.onnoff.apiPayload.ApiResponse;
import com.onnoff.onnoff.domain.user.dto.EnumInquiryResponseDTO;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;

@RestController
public class UserController {

}
Original file line number Diff line number Diff line change
@@ -1,33 +1,55 @@
package com.onnoff.onnoff.domain.user.converter;

import com.onnoff.onnoff.apiPayload.code.status.ErrorStatus;
import com.onnoff.onnoff.apiPayload.exception.GeneralException;
import com.onnoff.onnoff.auth.dto.LoginRequestDTO;
import com.onnoff.onnoff.auth.feignClient.dto.kakao.KakaoOauth2DTO;
import com.onnoff.onnoff.domain.user.User;
import com.onnoff.onnoff.domain.user.dto.UserResponseDTO;
import com.onnoff.onnoff.domain.user.enums.ExperienceYear;
import com.onnoff.onnoff.domain.user.enums.FieldOfWork;
import com.onnoff.onnoff.domain.user.enums.SocialType;

import java.util.EnumSet;

public class UserConverter {
public static User toUser(KakaoOauth2DTO.UserInfoResponseDTO response){
public static User toUser(KakaoOauth2DTO.UserInfoResponseDTO response, LoginRequestDTO.AdditionalInfo additionalInfo){
String fieldOfWork = additionalInfo.getFieldOfWork();
try{
FieldOfWork.valueOf(fieldOfWork);
}
catch (IllegalArgumentException e){
throw new GeneralException(ErrorStatus.INVALID_ENUM_VALUE);
}

ExperienceYear experienceYear = ExperienceYear.fromValue(additionalInfo.getExperienceYear());
return User.builder()
.oauthId(response.getSub())
.email(response.getEmail())
.name(response.getNickname())
.socialType(SocialType.KAKAO)
.fieldOfWork(Enum.valueOf(FieldOfWork.class ,additionalInfo.getFieldOfWork() ) )
.job(additionalInfo.getJob())
.experienceYear(experienceYear)
.build();
}
public static User toUser(LoginRequestDTO.AppleTokenValidateDTO request){
public static User toUser(LoginRequestDTO.AppleTokenValidateDTO request, LoginRequestDTO.AdditionalInfo additionalInfo){
ExperienceYear experienceYear = ExperienceYear.fromValue(additionalInfo.getExperienceYear());
String fullName = request.getFullName().getFamilyName() + request.getFullName().getGivenName();
return User.builder()
.oauthId(request.getOauthId())
.email(request.getEmail())
.name(request.getFullName())
.name(fullName)
.socialType(SocialType.APPLE)
.fieldOfWork(Enum.valueOf(FieldOfWork.class ,additionalInfo.getFieldOfWork() ) )
.job(additionalInfo.getJob())
.experienceYear(experienceYear)
.build();
}
public static UserResponseDTO.LoginDTO toLoginDTO(User user, String accessToken, String refreshToken){
public static UserResponseDTO.LoginDTO toLoginDTO(String accessToken, String refreshToken){
return UserResponseDTO.LoginDTO.builder()
.accessToken(accessToken)
.refreshToken(refreshToken)
.infoSet(user.isInfoSet())
.build();

}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
package com.onnoff.onnoff.domain.user.dto;

import com.onnoff.onnoff.domain.user.enums.ExperienceYear;
import com.onnoff.onnoff.domain.user.enums.FieldOfWork;

import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

public class EnumInquiryResponseDTO {

public static class FieldOfWorkResponseDTO{
public static List<String> getAllField() {
return Arrays.stream(FieldOfWork.values())
.map(Enum::name)
.collect(Collectors.toList());
}
}
public static class ExperienceYearResponseDTO{
public static List<String> getAllExperience() {
return Arrays.stream(ExperienceYear.values())
.map(ExperienceYear::getValue)
.collect(Collectors.toList());
}
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
package com.onnoff.onnoff.domain.user.dto;

import com.onnoff.onnoff.apiPayload.ApiResponse;
import com.onnoff.onnoff.domain.user.enums.ExperienceYear;
import com.onnoff.onnoff.domain.user.enums.FieldOfWork;
import com.onnoff.onnoff.domain.user.enums.SocialType;
import com.onnoff.onnoff.domain.user.enums.Status;
import lombok.AllArgsConstructor;
Expand All @@ -16,7 +18,6 @@ public class UserResponseDTO {
@NoArgsConstructor
@AllArgsConstructor
public static class LoginDTO{
private boolean infoSet;
private String accessToken;
private String refreshToken;
}
Expand All @@ -31,9 +32,9 @@ public static class UserDetailDTO{
private String name;
private String nickname;
private String email;
private String fieldOfWork;
private FieldOfWork fieldOfWork;
private String job;
private String experienceYear;
private ExperienceYear experienceYear;
private Status status;
private LocalDateTime inactiveDate;
private boolean receivePushNotification;
Expand All @@ -42,19 +43,4 @@ public static class UserDetailDTO{
private LocalDateTime updatedAt;
}

/**
* 스웨거 response에 제네릭 타입을 써주기 위한 클래스
*/
public static class ApiResponseLoginDTO extends ApiResponse<LoginDTO> {

public ApiResponseLoginDTO(Boolean isSuccess, String code, String message, LoginDTO result) {
super(isSuccess, code, message, result);
}
}
public static class ApiResponseUserDetailDTO extends ApiResponse<UserDetailDTO>{

public ApiResponseUserDetailDTO(Boolean isSuccess, String code, String message, UserDetailDTO result) {
super(isSuccess, code, message, result);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package com.onnoff.onnoff.domain.user.enums;


import com.onnoff.onnoff.apiPayload.code.status.ErrorStatus;
import com.onnoff.onnoff.apiPayload.exception.GeneralException;
import lombok.AllArgsConstructor;
import lombok.Getter;

@AllArgsConstructor
@Getter
public enum ExperienceYear {

THE_NEW("신입"),
THE_FIRST_YEAR("1년 이상 2년 미만"),
THE_SECOND_YEAR("2년 이상 3년 미만"),
THE_THIRD_YEAR("3년 이상 4년 미만"),
THE_FOURTH_YEAR("4년 이상 5년 미만"),
THE_FIFTH_YEAR_OR_MORE("5년 이상"),
THE_SENIOR("시니어");
private final String value;

public static ExperienceYear fromValue(String value) {
for (ExperienceYear experienceYear : ExperienceYear.values()) {
if (experienceYear.getValue().equals(value)) {
return experienceYear;
}
}
throw new GeneralException(ErrorStatus.INVALID_ENUM_VALUE);
}
}
15 changes: 15 additions & 0 deletions src/main/java/com/onnoff/onnoff/domain/user/enums/FieldOfWork.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.onnoff.onnoff.domain.user.enums;


import lombok.AllArgsConstructor;

@AllArgsConstructor
public enum FieldOfWork {

서비스업, 의료_제약_복지, 제조_화학,
판매_유통, IT_웹_통신, 건설업,
교육업, 미디어_디자인, 은행_금융업,
기관_협회, 비즈니스_투자, 물류_무역업,
법률_법집행기관, 방송_광고_엔터테인먼트, 여행_숙박_음식점업,
부동산_임대업
}

0 comments on commit d5d233c

Please sign in to comment.