diff --git a/src/main/java/org/nova/backend/auth/adapter/web/AuthApiDocument.java b/src/main/java/org/nova/backend/auth/adapter/web/AuthApiDocument.java index de2cc88b..874cee06 100644 --- a/src/main/java/org/nova/backend/auth/adapter/web/AuthApiDocument.java +++ b/src/main/java/org/nova/backend/auth/adapter/web/AuthApiDocument.java @@ -3,6 +3,7 @@ import io.swagger.v3.oas.annotations.Operation; import io.swagger.v3.oas.annotations.media.Content; import io.swagger.v3.oas.annotations.media.ExampleObject; +import io.swagger.v3.oas.annotations.media.Schema; import io.swagger.v3.oas.annotations.responses.ApiResponse; import io.swagger.v3.oas.annotations.responses.ApiResponses; import io.swagger.v3.oas.annotations.tags.Tag; @@ -10,6 +11,7 @@ import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target; +import org.nova.backend.auth.application.dto.response.LoginResponse; @Tag(name = "회원 인증 API", description = "회원가입 로그인 API") public @interface AuthApiDocument { @@ -56,15 +58,19 @@ @Operation(summary = "로그인", description = "회원가입된 정보로 본인 인증 로그인") @ApiResponses({ - @ApiResponse(responseCode = "200", description = "로그인 성공"), + @ApiResponse( + responseCode = "200", + description = "로그인 성공", + content = @Content(mediaType = "application/json", + schema = @Schema(implementation = LoginResponse.class)) + ), @ApiResponse(responseCode = "400", description = "잘못된 요청 데이터"), @ApiResponse(responseCode = "401", description = "로그인 실패. 학번 또는 비밀번호를 다시 확인해주세요."), @ApiResponse(responseCode = "500", description = "서버 오류") }) @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) - @interface LoginApiDoc { - } + @interface LoginApiDoc {} @Operation(summary = "로그아웃", description = "로그인한 정보를 삭제합니다. AUTH_TOKEN 담긴 쿠키 삭제") @ApiResponses({ @@ -99,8 +105,7 @@ ✔️ 발급된 임시 비밀번호는 10자리 랜덤 문자열이며, 기존 비밀번호를 대체하여 저장됩니다. ✔️ 사용자의 비밀번호는 암호화되어 저장되며, `isTempPassword` 플래그가 true로 설정됩니다. ✔️ 로그인 시 `isTempPassword`가 true인 사용자는 비밀번호 변경 페이지로 리다이렉트해야 합니다. - """, - tags = {"Password Reset API"} + """ ) @ApiResponses({ @ApiResponse(responseCode = "200", description = "임시 비밀번호 이메일 전송 성공"), diff --git a/src/main/java/org/nova/backend/auth/application/dto/dto/CustomUserDetails.java b/src/main/java/org/nova/backend/auth/application/dto/dto/CustomUserDetails.java index 052c3822..d077cd1c 100644 --- a/src/main/java/org/nova/backend/auth/application/dto/dto/CustomUserDetails.java +++ b/src/main/java/org/nova/backend/auth/application/dto/dto/CustomUserDetails.java @@ -46,4 +46,8 @@ public String getStudentNumber(){ public Member getMember() { return member; } + + public boolean isTempPassword() { + return member.isTempPassword(); + } } diff --git a/src/main/java/org/nova/backend/auth/application/dto/response/LoginResponse.java b/src/main/java/org/nova/backend/auth/application/dto/response/LoginResponse.java new file mode 100644 index 00000000..f99994cc --- /dev/null +++ b/src/main/java/org/nova/backend/auth/application/dto/response/LoginResponse.java @@ -0,0 +1,11 @@ +package org.nova.backend.auth.application.dto.response; + +import lombok.AllArgsConstructor; +import lombok.Getter; + +@Getter +@AllArgsConstructor +public class LoginResponse { + private String message; + private boolean isTempPassword; +} \ No newline at end of file diff --git a/src/main/java/org/nova/backend/member/application/service/MemberService.java b/src/main/java/org/nova/backend/member/application/service/MemberService.java index 847a0b94..aa43a2b9 100644 --- a/src/main/java/org/nova/backend/member/application/service/MemberService.java +++ b/src/main/java/org/nova/backend/member/application/service/MemberService.java @@ -192,6 +192,11 @@ public MemberSimpleProfileResponse getSimpleProfile(UUID memberId) { public MyPageMemberResponse getMemberProfile(UUID profileMemberId, UUID loginMemberId) { Member profileMember = findByMemberId(profileMemberId); boolean isLoginMember = isLoginMember(profileMemberId, loginMemberId); + + if (!isLoginMember && profileMember.getStudentNumber().equals(adminStudentNumber)) { + throw new MemberDomainException("관리자 프로필은 조회할 수 없습니다.", HttpStatus.FORBIDDEN); + } + if (!isLoginMember) { findByMemberId(loginMemberId); } diff --git a/src/main/java/org/nova/backend/shared/security/LoginFilter.java b/src/main/java/org/nova/backend/shared/security/LoginFilter.java index c3440c97..6c036a03 100644 --- a/src/main/java/org/nova/backend/shared/security/LoginFilter.java +++ b/src/main/java/org/nova/backend/shared/security/LoginFilter.java @@ -67,13 +67,35 @@ private AuthLoginDTO getLoginDataFromHTTPRequest(HttpServletRequest request) { @Override - protected void successfulAuthentication(HttpServletRequest request, HttpServletResponse response, FilterChain chain, - Authentication authentication) { + protected void successfulAuthentication( + HttpServletRequest request, + HttpServletResponse response, + FilterChain chain, + Authentication authentication + ) throws IOException { log.info("로그인 성공"); + CustomUserDetails customUserDetails = (CustomUserDetails) authentication.getPrincipal(); String token = createAuthorizationToken(authentication); - //쿠키에 auth 토큰 담기 + // JSON 응답 추가 + response.setContentType("application/json"); + response.setCharacterEncoding("UTF-8"); + + boolean isTempPassword = customUserDetails.isTempPassword(); + + String jsonResponse = String.format(""" + { + "status": 200, + "message": "success", + "data": { + "message": "로그인 성공", + "tempPassword": %s + } + } + """, isTempPassword); + + //헤더 설정 Cookie cookie = new Cookie("AUTH_TOKEN", token); cookie.setHttpOnly(true); cookie.setPath("/"); @@ -84,6 +106,8 @@ protected void successfulAuthentication(HttpServletRequest request, HttpServletR token, 60 * 60 * 5, isSecureCookie ? "; Secure" : "" )); + + response.getWriter().write(jsonResponse); } /*