Skip to content

Commit

Permalink
FIX: (#145) 인증도메인 표현 계층을 재정의한다
Browse files Browse the repository at this point in the history
  • Loading branch information
anxi01 committed Feb 20, 2025
1 parent 2ba4dfe commit 9235c32
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 232 deletions.
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
package com.zerozero.auth.presentation;

import com.zerozero.auth.application.AuthorizeOAuthUseCase;
import java.net.URI;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.view.RedirectView;

import java.net.URI;

@Controller
@RequestMapping("/oauth")
@RequiredArgsConstructor
public class AuthorizeOAuthController {

private final AuthorizeOAuthUseCase authorizeOAuthUseCase;
private final AuthorizeOAuthUseCase authorizeOAuthUseCase;

@GetMapping("/{providerName}")
public RedirectView authorizeOAuth(@PathVariable String providerName) {
URI authUrl = authorizeOAuthUseCase.getAuthorizeUrl(providerName);
return new RedirectView(authUrl.toASCIIString());
}
@GetMapping("/{providerName}")
public RedirectView authorizeOAuth(@PathVariable String providerName) {
URI authUrl = authorizeOAuthUseCase.getAuthorizeUrl(providerName);
return new RedirectView(authUrl.toASCIIString());
}
}

Original file line number Diff line number Diff line change
@@ -1,101 +1,40 @@
package com.zerozero.auth.presentation;

import com.zerozero.auth.application.HandleOAuthLoginUseCase;
import com.zerozero.auth.application.HandleOAuthLoginUseCase.HandleOAuthLoginErrorCode;
import com.zerozero.auth.presentation.HandleOAuthLoginController.HandleOAuthLoginResponse.Token;
import com.zerozero.configuration.interceptor.Authorization;
import com.zerozero.auth.exception.AuthErrorType;
import com.zerozero.auth.presentation.response.LoginResponse;
import com.zerozero.configuration.swagger.ApiErrorCode;
import com.zerozero.core.application.BaseRequest;
import com.zerozero.core.application.BaseResponse;
import com.zerozero.core.domain.vo.User;
import com.zerozero.core.exception.error.GlobalErrorCode;
import com.zerozero.core.support.error.GlobalErrorType;
import com.zerozero.core.support.response.ApiResponse;
import com.zerozero.user.exception.UserErrorType;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.Optional;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@Tag(name = "User", description = "사용자")
public class HandleOAuthLoginController {

private final HandleOAuthLoginUseCase handleOAuthLoginUseCase;

@Operation(
summary = "사용자 소셜 로그인 API",
description = "인가 코드를 사용하여 사용자의 로그인을 처리합니다. \n\n 회원가입이 완료된 상태(COMPLETED)라면 메인 페이지로 리다이렉트되며, 가입 과정에서 중단된 사용자(PENDING)는 회원가입 페이지로 리다이렉트됩니다.",
operationId = "/login"
)
@ApiErrorCode({GlobalErrorCode.class, HandleOAuthLoginErrorCode.class})
@GetMapping("/login/{providerName}")
public ResponseEntity<HandleOAuthLoginResponse> handleOAuthLogin(
@ParameterObject HandleOAuthLoginRequest request, @PathVariable String providerName) {
HandleOAuthLoginUseCase.HandleOAuthLoginResponse handleOAuthLoginResponse = handleOAuthLoginUseCase.execute(
HandleOAuthLoginUseCase.HandleOAuthLoginRequest.builder()
.code(request.getCode())
.providerName(providerName)
.build());
if (handleOAuthLoginResponse == null || !handleOAuthLoginResponse.isSuccess()) {
Optional.ofNullable(handleOAuthLoginResponse)
.map(BaseResponse::getErrorCode)
.ifPresentOrElse(errorCode -> {
throw errorCode.toException();
}, () -> {
throw GlobalErrorCode.INTERNAL_ERROR.toException();
});
private final HandleOAuthLoginUseCase handleOAuthLoginUseCase;

@Operation(
summary = "사용자 소셜 로그인 API",
description = "인가 코드를 사용하여 사용자의 로그인을 처리합니다. \n\n 회원가입이 완료된 상태(COMPLETED)라면 메인 페이지로 리다이렉트되며, 가입 과정에서 중단된 사용자(PENDING)는 회원가입 페이지로 리다이렉트됩니다.",
operationId = "/login"
)
@ApiErrorCode({GlobalErrorType.class, AuthErrorType.class, UserErrorType.class})
@GetMapping("/login/{providerName}")
public ApiResponse<LoginResponse> handleOAuthLogin(
@RequestParam @Schema(description = "소셜 로그인 시 사용되는 인가 코드") String code,
@PathVariable String providerName) {
LoginResponse loginResponse = handleOAuthLoginUseCase.execute(code, providerName);
return ApiResponse.success(loginResponse);
}
return ResponseEntity.ok(
HandleOAuthLoginResponse.builder()
.user(handleOAuthLoginResponse.getUser())
.token(new Token(handleOAuthLoginResponse.getToken().getAccessToken().getToken(),
handleOAuthLoginResponse.getToken().getRefreshToken().getToken()))
.build());
}


@ToString
@Getter
@Setter
@SuperBuilder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@Schema(description = "사용자 소셜 로그인 응답")
public static class HandleOAuthLoginResponse extends BaseResponse<GlobalErrorCode> {

private User user;

@Schema(description = "액세스 토큰과 리프레시 토큰")
private Token token;

record Token(String accessToken, String refreshToken) {

}
}

@ToString
@Getter
@Setter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@Schema(description = "사용자 소셜 로그인 요청")
public static class HandleOAuthLoginRequest implements BaseRequest {

@Schema(description = "소셜 로그인 시 사용되는 인가 코드")
private String code;
}
}
Original file line number Diff line number Diff line change
@@ -1,98 +1,36 @@
package com.zerozero.auth.presentation;

import com.zerozero.auth.application.RefreshUserTokenUseCase;
import com.zerozero.auth.application.RefreshUserTokenUseCase.RefreshUserTokenErrorCode;
import com.zerozero.auth.application.RefreshUserTokenUseCase.RefreshUserTokenResponse.Tokens;
import com.zerozero.auth.presentation.RefreshUserTokenController.RefreshUserTokenResponse.Token;
import com.zerozero.auth.exception.AuthErrorType;
import com.zerozero.auth.presentation.response.TokenResponse;
import com.zerozero.configuration.swagger.ApiErrorCode;
import com.zerozero.core.application.BaseRequest;
import com.zerozero.core.application.BaseResponse;
import com.zerozero.core.domain.vo.AccessToken;
import com.zerozero.core.domain.vo.RefreshToken;
import com.zerozero.core.exception.error.GlobalErrorCode;
import com.zerozero.core.support.error.GlobalErrorType;
import com.zerozero.core.support.response.ApiResponse;
import com.zerozero.user.exception.UserErrorType;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import java.util.Optional;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.NoArgsConstructor;
import lombok.RequiredArgsConstructor;
import lombok.Setter;
import lombok.ToString;
import lombok.experimental.SuperBuilder;
import org.springdoc.core.annotations.ParameterObject;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequiredArgsConstructor
@Tag(name = "User", description = "사용자")
public class RefreshUserTokenController {

private final RefreshUserTokenUseCase refreshUserTokenUseCase;

@Operation(
summary = "토큰 재발급 API",
description = "사용자의 리프레시 토큰을 통해 토큰을 재발급합니다.",
operationId = "/refresh/token"
)
@ApiErrorCode({GlobalErrorCode.class, RefreshUserTokenErrorCode.class})
@GetMapping("/refresh/token")
public ResponseEntity<RefreshUserTokenResponse> refreshUserToken(@ParameterObject RefreshUserTokenRequest refreshUserTokenRequest) {
RefreshUserTokenUseCase.RefreshUserTokenResponse refreshUserTokenResponse = refreshUserTokenUseCase.execute(
RefreshUserTokenUseCase.RefreshUserTokenRequest.builder()
.refreshToken(RefreshToken.of(refreshUserTokenRequest.getRefreshToken()))
.build());
if (refreshUserTokenResponse == null || !refreshUserTokenResponse.isSuccess()) {
Optional.ofNullable(refreshUserTokenResponse)
.map(BaseResponse::getErrorCode)
.ifPresentOrElse(errorCode -> {
throw errorCode.toException();
}, () -> {
throw GlobalErrorCode.INTERNAL_ERROR.toException();
});
}
return ResponseEntity.ok(RefreshUserTokenResponse.builder()
.token(new Token(
Optional.ofNullable(refreshUserTokenResponse.getTokens()).map(Tokens::getAccessToken)
.map(AccessToken::getToken)
.orElse(null),
Optional.ofNullable(refreshUserTokenResponse.getTokens()).map(Tokens::getRefreshToken)
.map(RefreshToken::getToken)
.orElse(null)))
.build());
}

@ToString
@Getter
@Setter
@SuperBuilder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@Schema(description = "토큰 재발급 응답")
public static class RefreshUserTokenResponse extends BaseResponse<GlobalErrorCode> {

@Schema(description = "액세스 토큰과 리프레시 토큰")
private Token token;

record Token(String accessToken, String refreshToken) {
private final RefreshUserTokenUseCase refreshUserTokenUseCase;

@Operation(
summary = "토큰 재발급 API",
description = "사용자의 리프레시 토큰을 통해 토큰을 재발급합니다.",
operationId = "/refresh/token"
)
@ApiErrorCode({GlobalErrorType.class, AuthErrorType.class, UserErrorType.class})
@GetMapping("/refresh/token")
public ApiResponse<TokenResponse> refreshUserToken(@RequestParam String refreshToken) {
TokenResponse tokenResponse = refreshUserTokenUseCase.execute(refreshToken);
return ApiResponse.success(tokenResponse);
}
}

@ToString
@Getter
@Setter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@Schema(description = "토큰 재발급 요청")
public static class RefreshUserTokenRequest implements BaseRequest {

@Schema(description = "리프레시 토큰")
private String refreshToken;
}
}
Original file line number Diff line number Diff line change
@@ -1,86 +1,43 @@
package com.zerozero.auth.presentation;

import com.zerozero.auth.application.RegisterUserUseCase;
import com.zerozero.auth.application.RegisterUserUseCase.RegisterUserErrorCode;
import com.zerozero.auth.exception.AuthErrorType;
import com.zerozero.auth.presentation.request.RegisterRequest;
import com.zerozero.configuration.interceptor.Authorization;
import com.zerozero.configuration.swagger.ApiErrorCode;
import com.zerozero.core.application.BaseRequest;
import com.zerozero.core.application.BaseResponse;
import com.zerozero.core.exception.error.GlobalErrorCode;
import com.zerozero.core.support.error.GlobalErrorType;
import com.zerozero.core.support.response.ApiResponse;
import com.zerozero.user.domain.response.UserResponse;
import com.zerozero.user.exception.UserErrorType;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.media.Schema;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import jakarta.validation.constraints.NotNull;
import lombok.*;
import lombok.experimental.SuperBuilder;
import org.springframework.http.ResponseEntity;
import lombok.RequiredArgsConstructor;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
import org.springframework.web.bind.annotation.RestController;

import java.util.Optional;

@RestController
@RequiredArgsConstructor
@Tag(name = "User", description = "사용자")
public class RegisterUserController {

private final RegisterUserUseCase registerUserUseCase;

@Operation(
summary = "사용자 회원가입 API",
description = "사용자의 개인 정보를 통해 회원을 가입합니다.",
operationId = "/register"
)
@ApiErrorCode({GlobalErrorCode.class, RegisterUserErrorCode.class})
@Authorization
@PostMapping("/register")
public ResponseEntity<RegisterUserResponse> registerUser(@Valid @RequestBody RegisterUserRequest registerUserRequest,
@Parameter(hidden = true) @RequestHeader("Authorization") String authorizationHeader) {
RegisterUserUseCase.RegisterUserResponse registerUserResponse = registerUserUseCase.execute(
RegisterUserUseCase.RegisterUserRequest.builder()
.accessToken(authorizationHeader.substring(7))
.nickname(registerUserRequest.getNickname())
.build());
if (registerUserResponse == null || !registerUserResponse.isSuccess()) {
Optional.ofNullable(registerUserResponse)
.map(BaseResponse::getErrorCode)
.ifPresentOrElse(errorCode -> {
throw errorCode.toException();
}, () -> {
throw GlobalErrorCode.INTERNAL_ERROR.toException();
});
private final RegisterUserUseCase registerUserUseCase;

@Operation(
summary = "사용자 회원가입 API",
description = "사용자의 개인 정보를 통해 회원을 가입합니다.",
operationId = "/register"
)
@ApiErrorCode({GlobalErrorType.class, AuthErrorType.class, UserErrorType.class})
@Authorization
@PostMapping("/register")
public ApiResponse<UserResponse> registerUser(@Valid @RequestBody RegisterRequest registerRequest,
@Parameter(hidden = true) @RequestHeader("Authorization") String authorizationHeader) {
UserResponse userResponse = registerUserUseCase.execute(registerRequest, authorizationHeader.substring(7));
return ApiResponse.success(userResponse);
}
return ResponseEntity.ok(RegisterUserResponse.builder()
.user(registerUserResponse.getUser())
.build());
}

@ToString
@Getter
@Setter
@SuperBuilder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@Schema(description = "사용자 회원가입 응답")
public static class RegisterUserResponse extends BaseResponse<GlobalErrorCode> {

private com.zerozero.core.domain.vo.User user;
}

@ToString
@Getter
@Setter
@Builder
@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor(access = AccessLevel.PROTECTED)
@Schema(description = "사용자 회원가입 요청")
public static class RegisterUserRequest implements BaseRequest {

@NotNull(message = "닉네임은 필수 데이터입니다.")
@Schema(description = "닉네임", example = "제로")
private String nickname;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.zerozero.auth.presentation.request;

import io.swagger.v3.oas.annotations.media.Schema;
import jakarta.validation.constraints.NotNull;

public record RegisterRequest(
@NotNull(message = "닉네임은 필수 데이터입니다.")
@Schema(description = "닉네임", example = "제로")
String nickname
) {
}
Loading

0 comments on commit 9235c32

Please sign in to comment.