Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions src/main/java/org/runimo/runimo/RunimoApplication.java
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
@SpringBootApplication
public class RunimoApplication {

public static void main(String[] args) {
SpringApplication.run(RunimoApplication.class, args);
}
public static void main(String[] args) {
SpringApplication.run(RunimoApplication.class, args);
}

}
179 changes: 91 additions & 88 deletions src/main/java/org/runimo/runimo/auth/controller/AuthController.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.tags.Tag;
import jakarta.validation.Valid;
import java.net.URI;
import lombok.RequiredArgsConstructor;
import org.runimo.runimo.auth.controller.request.AppleLoginRequest;
import org.runimo.runimo.auth.controller.request.AuthSignupRequest;
Expand All @@ -22,104 +23,106 @@
import org.runimo.runimo.exceptions.RegisterErrorResponse;
import org.runimo.runimo.user.enums.UserHttpResponseCode;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.*;

import java.net.URI;
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.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@Tag(name = "Auth API", description = "인증 관련 API 모음")
@RestController
@RequestMapping("/api/v1/auth")
@RequiredArgsConstructor
public class AuthController {

private final OidcService oidcService;
private final TokenRefreshService tokenRefreshService;
private final SignUpUsecase signUpUsecase;
private final OidcService oidcService;
private final TokenRefreshService tokenRefreshService;
private final SignUpUsecase signUpUsecase;

@Operation(summary = "카카오 소셜 로그인", description = "카카오 OIDC 토큰을 이용하여 로그인합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "로그인 성공"),
@ApiResponse(responseCode = "401", description = "인증 실패",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "404", description = "등록되지 않은 사용자",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = RegisterErrorResponse.class)))
})
@PostMapping("/kakao")
public ResponseEntity<SuccessResponse<AuthResponse>> kakaoLogin(
@RequestBody KakaoLoginRequest request
) {
AuthResponse res = oidcService.kakaoLogin(request.oidcToken());
return ResponseEntity.ok().body(
SuccessResponse.of(
UserHttpResponseCode.LOGIN_SUCCESS,
res
)
);
}
@Operation(summary = "카카오 소셜 로그인", description = "카카오 OIDC 토큰을 이용하여 로그인합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "로그인 성공"),
@ApiResponse(responseCode = "401", description = "인증 실패",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "404", description = "등록되지 않은 사용자",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = RegisterErrorResponse.class)))
})
@PostMapping("/kakao")
public ResponseEntity<SuccessResponse<AuthResponse>> kakaoLogin(
@RequestBody KakaoLoginRequest request
) {
AuthResponse res = oidcService.kakaoLogin(request.oidcToken());
return ResponseEntity.ok().body(
SuccessResponse.of(
UserHttpResponseCode.LOGIN_SUCCESS,
res
)
);
}

@Operation(summary = "애플 소셜 로그인", description = "애플 OIDC 토큰을 이용하여 로그인합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "로그인 성공"),
@ApiResponse(responseCode = "401", description = "인증 실패",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "404", description = "등록되지 않은 사용자",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = RegisterErrorResponse.class)))
})
@PostMapping("/apple")
public ResponseEntity<SuccessResponse<AuthResponse>> appleLogin(
@RequestBody final AppleLoginRequest request
) {
AuthResponse res = oidcService.appleLogin(request.authCode(), request.codeVerifier());
return ResponseEntity.ok().body(
SuccessResponse.of(
UserHttpResponseCode.LOGIN_SUCCESS,
res
)
);
}
@Operation(summary = "애플 소셜 로그인", description = "애플 OIDC 토큰을 이용하여 로그인합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "로그인 성공"),
@ApiResponse(responseCode = "401", description = "인증 실패",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "404", description = "등록되지 않은 사용자",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = RegisterErrorResponse.class)))
})
@PostMapping("/apple")
public ResponseEntity<SuccessResponse<AuthResponse>> appleLogin(
@RequestBody final AppleLoginRequest request
) {
AuthResponse res = oidcService.appleLogin(request.authCode(), request.codeVerifier());
return ResponseEntity.ok().body(
SuccessResponse.of(
UserHttpResponseCode.LOGIN_SUCCESS,
res
)
);
}

@Operation(summary = "사용자 회원가입 및 로그인", description = "사용자가 OIDC 토큰을 사용하여 회원가입 후 로그인합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "201", description = "회원가입 성공"),
@ApiResponse(responseCode = "400", description = "잘못된 데이터",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "409", description = "이미 존재하는 사용자")
})
@PostMapping("/signup")
public ResponseEntity<SuccessResponse<SignupUserResponse>> signupAndLogin(
@Valid @RequestBody AuthSignupRequest request) {
SignupUserResponse authResult = signUpUsecase.register(
request.toUserSignupCommand()
);
return ResponseEntity.created(URI.create("/api/v1/user" + authResult.userId()))
.body(SuccessResponse.of(
UserHttpResponseCode.SIGNUP_SUCCESS,
authResult)
@Operation(summary = "사용자 회원가입 및 로그인", description = "사용자가 OIDC 토큰을 사용하여 회원가입 후 로그인합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "201", description = "회원가입 성공"),
@ApiResponse(responseCode = "400", description = "잘못된 데이터",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = ErrorResponse.class))),
@ApiResponse(responseCode = "409", description = "이미 존재하는 사용자")
})
@PostMapping("/signup")
public ResponseEntity<SuccessResponse<SignupUserResponse>> signupAndLogin(
@Valid @RequestBody AuthSignupRequest request) {
SignupUserResponse authResult = signUpUsecase.register(
request.toUserSignupCommand()
);
}
return ResponseEntity.created(URI.create("/api/v1/user" + authResult.userId()))
.body(SuccessResponse.of(
UserHttpResponseCode.SIGNUP_SUCCESS,
authResult)
);
}

@Operation(summary = "토큰 갱신", description = "리프레시 토큰을 사용하여 액세스 토큰을 갱신합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "토큰 갱신 성공"),
@ApiResponse(responseCode = "401", description = "유효하지 않은 토큰",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = ErrorResponse.class))),
})
@PostMapping("/refresh")
public ResponseEntity<SuccessResponse<TokenPair>> refreshToken(
@RequestHeader("Authorization") String refreshToken) {
String token = refreshToken.replace("Bearer ", "");
TokenPair newTokens = tokenRefreshService.refreshAccessToken(token);
return ResponseEntity.ok().body(
SuccessResponse.of(
UserHttpResponseCode.REFRESH_SUCCESS,
newTokens
)
);
}
@Operation(summary = "토큰 갱신", description = "리프레시 토큰을 사용하여 액세스 토큰을 갱신합니다.")
@ApiResponses(value = {
@ApiResponse(responseCode = "200", description = "토큰 갱신 성공"),
@ApiResponse(responseCode = "401", description = "유효하지 않은 토큰",
content = @Content(mediaType = "application/json",
schema = @Schema(implementation = ErrorResponse.class))),
})
@PostMapping("/refresh")
public ResponseEntity<SuccessResponse<TokenPair>> refreshToken(
@RequestHeader("Authorization") String refreshToken) {
String token = refreshToken.replace("Bearer ", "");
TokenPair newTokens = tokenRefreshService.refreshAccessToken(token);
return ResponseEntity.ok().body(
SuccessResponse.of(
UserHttpResponseCode.REFRESH_SUCCESS,
newTokens
)
);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,5 @@ public record AppleLoginRequest(
@Schema(description = "Code Verifier")
@NotBlank String codeVerifier
) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ public record AuthSignupRequest(
@Schema(description = "프로필 이미지 URL", example = "https://example.com/image.jpg")
@URL String imgUrl
) {
public UserSignupCommand toUserSignupCommand() {
return new UserSignupCommand(registerToken, nickname, imgUrl);
}

public UserSignupCommand toUserSignupCommand() {
return new UserSignupCommand(registerToken, nickname, imgUrl);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,5 @@ public record KakaoLoginRequest(
@Schema(description = "카카오 oidc토큰")
String oidcToken
) {

}
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@

public class SignUpException extends BusinessException {

public SignUpException(CustomResponseCode errorCode) {
super(errorCode);
}
public SignUpException(CustomResponseCode errorCode) {
super(errorCode);
}

protected SignUpException(CustomResponseCode errorCode, String logMessage) {
super(errorCode, logMessage);
}
protected SignUpException(CustomResponseCode errorCode, String logMessage) {
super(errorCode, logMessage);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,26 @@


public class UnRegisteredUserException extends BusinessException {
private final String temporalRegisterToken;

protected UnRegisteredUserException(CustomResponseCode errorCode, String temporalRegisterToken) {
super(errorCode);
this.temporalRegisterToken = temporalRegisterToken;
}
private final String temporalRegisterToken;

protected UnRegisteredUserException(CustomResponseCode errorCode, String logMessage, String temporalRegisterToken) {
super(errorCode, logMessage);
this.temporalRegisterToken = temporalRegisterToken;
}
protected UnRegisteredUserException(CustomResponseCode errorCode,
String temporalRegisterToken) {
super(errorCode);
this.temporalRegisterToken = temporalRegisterToken;
}

public static UnRegisteredUserException of(CustomResponseCode errorCode, String token) {
return new UnRegisteredUserException(errorCode, token);
}
protected UnRegisteredUserException(CustomResponseCode errorCode, String logMessage,
String temporalRegisterToken) {
super(errorCode, logMessage);
this.temporalRegisterToken = temporalRegisterToken;
}

public String getTemporalRegisterToken() {
return temporalRegisterToken;
}
public static UnRegisteredUserException of(CustomResponseCode errorCode, String token) {
return new UnRegisteredUserException(errorCode, token);
}

public String getTemporalRegisterToken() {
return temporalRegisterToken;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@
import org.runimo.runimo.exceptions.code.CustomResponseCode;

public class UserJwtException extends BusinessException {
protected UserJwtException(CustomResponseCode errorCode) {
super(errorCode);
}

public UserJwtException(CustomResponseCode errorCode, String logMessage) {
super(errorCode, logMessage);
}
protected UserJwtException(CustomResponseCode errorCode) {
super(errorCode);
}

public static UserJwtException of(CustomResponseCode errorCode) {
return new UserJwtException(errorCode, errorCode.getLogMessage());
}
public UserJwtException(CustomResponseCode errorCode, String logMessage) {
super(errorCode, logMessage);
}

public static UserJwtException of(CustomResponseCode errorCode) {
return new UserJwtException(errorCode, errorCode.getLogMessage());
}
}
Loading