Skip to content

Commit 5a1f682

Browse files
authored
Merge pull request #37 from assu-org/fix/#33-login-out-fix
[Fix/#33] 로그인 / 로그아웃 / 리프레시 fix
2 parents 47bdd51 + 8bacea0 commit 5a1f682

30 files changed

Lines changed: 1019 additions & 751 deletions

src/main/java/com/assu/server/domain/auth/controller/AuthController.java

Lines changed: 12 additions & 85 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package com.assu.server.domain.auth.controller;
22

3-
import com.assu.server.domain.auth.dto.login.LoginRequest;
3+
import com.assu.server.domain.auth.dto.login.CommonLoginRequest;
44
import com.assu.server.domain.auth.dto.login.LoginResponse;
55
import com.assu.server.domain.auth.dto.login.RefreshResponse;
66
import com.assu.server.domain.auth.dto.login.StudentLoginRequest;
@@ -13,7 +13,6 @@
1313
import com.assu.server.domain.auth.service.LogoutService;
1414
import com.assu.server.domain.auth.service.PhoneAuthService;
1515
import com.assu.server.domain.auth.service.SignUpService;
16-
import com.assu.server.domain.common.enums.UserRole;
1716
import com.assu.server.global.apiPayload.BaseResponse;
1817
import com.assu.server.global.apiPayload.code.status.SuccessStatus;
1918
import io.swagger.v3.oas.annotations.Operation;
@@ -22,16 +21,12 @@
2221
import io.swagger.v3.oas.annotations.enums.ParameterIn;
2322
import io.swagger.v3.oas.annotations.media.Content;
2423
import io.swagger.v3.oas.annotations.media.Schema;
25-
import io.swagger.v3.oas.annotations.responses.ApiResponse;
26-
import io.swagger.v3.oas.annotations.responses.ApiResponses;
2724
import io.swagger.v3.oas.annotations.tags.Tag;
2825
import jakarta.validation.Valid;
2926
import lombok.RequiredArgsConstructor;
3027
import org.springframework.http.MediaType;
31-
import org.springframework.http.ResponseEntity;
3228
import org.springframework.web.bind.annotation.*;
3329
import org.springframework.web.multipart.MultipartFile;
34-
import org.springframework.web.multipart.MultipartRequest;
3530

3631
@Tag(name = "Auth", description = "인증/회원가입 API")
3732
@RestController
@@ -50,12 +45,6 @@ public class AuthController {
5045
"- 입력한 휴대폰 번호로 1회용 인증번호(OTP)를 발송합니다.\n" +
5146
"- 유효시간/재요청 제한 정책은 서버 설정에 따릅니다."
5247
)
53-
@ApiResponses({
54-
@ApiResponse(responseCode = "200", description = "인증번호 발송 성공",
55-
content = @Content(schema = @Schema(implementation = BaseResponse.class))),
56-
@ApiResponse(responseCode = "400", description = "잘못된 요청 (형식/필수값 오류)",
57-
content = @Content(schema = @Schema(implementation = BaseResponse.class)))
58-
})
5948
@PostMapping("/phone-numbers/send")
6049
public BaseResponse<Void> sendAuthNumber(
6150
@RequestBody @Valid PhoneAuthRequestDTO.PhoneAuthSendRequest request
@@ -70,12 +59,6 @@ public BaseResponse<Void> sendAuthNumber(
7059
"- 발송된 인증번호(OTP)를 검증합니다.\n" +
7160
"- 성공 시 서버에 휴대폰 인증 상태가 기록됩니다."
7261
)
73-
@ApiResponses({
74-
@ApiResponse(responseCode = "200", description = "인증번호 검증 성공",
75-
content = @Content(schema = @Schema(implementation = BaseResponse.class))),
76-
@ApiResponse(responseCode = "400", description = "인증 실패/만료/형식 오류",
77-
content = @Content(schema = @Schema(implementation = BaseResponse.class)))
78-
})
7962
@PostMapping("/phone-numbers/verify")
8063
public BaseResponse<Void> checkAuthNumber(
8164
@RequestBody @Valid PhoneAuthRequestDTO.PhoneAuthVerifyRequest request
@@ -94,14 +77,6 @@ public BaseResponse<Void> checkAuthNumber(
9477
"- 처리: users + ssu_auth 등 가입 레코드 생성, 휴대폰 인증 여부 확인.\n" +
9578
"- 성공 시 201(Created)과 생성된 memberId 반환."
9679
)
97-
@ApiResponses({
98-
@ApiResponse(responseCode = "201", description = "회원가입 성공",
99-
content = @Content(schema = @Schema(implementation = SignUpResponse.class))),
100-
@ApiResponse(responseCode = "400", description = "검증 실패/형식 오류",
101-
content = @Content(schema = @Schema(implementation = BaseResponse.class))),
102-
@ApiResponse(responseCode = "409", description = "중복(전화번호 등)으로 인한 충돌",
103-
content = @Content(schema = @Schema(implementation = BaseResponse.class)))
104-
})
10580
@PostMapping(value = "/signup/student", consumes = MediaType.APPLICATION_JSON_VALUE)
10681
public BaseResponse<SignUpResponse> signupStudent(
10782
@Valid @RequestBody StudentSignUpRequest request) {
@@ -116,14 +91,6 @@ public BaseResponse<SignUpResponse> signupStudent(
11691
"- 처리: users + common_auth 생성, 이메일 중복/비밀번호 규칙 검증.\n" +
11792
"- 성공 시 201(Created)과 생성된 memberId 반환."
11893
)
119-
@ApiResponses({
120-
@ApiResponse(responseCode = "201", description = "회원가입 성공",
121-
content = @Content(schema = @Schema(implementation = SignUpResponse.class))),
122-
@ApiResponse(responseCode = "400", description = "검증 실패/형식 오류(비밀번호 불일치 등)",
123-
content = @Content(schema = @Schema(implementation = BaseResponse.class))),
124-
@ApiResponse(responseCode = "409", description = "중복(전화/이메일)으로 인한 충돌",
125-
content = @Content(schema = @Schema(implementation = BaseResponse.class)))
126-
})
12794
@PostMapping(value = "/signup/partner", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
12895
public BaseResponse<SignUpResponse> signupPartner(
12996
@Valid @RequestPart("request")
@@ -155,14 +122,6 @@ public BaseResponse<SignUpResponse> signupPartner(
155122
"- 처리: users + common_auth 생성, 이메일 중복/비밀번호 규칙 검증.\n" +
156123
"- 성공 시 201(Created)과 생성된 memberId 반환."
157124
)
158-
@ApiResponses({
159-
@ApiResponse(responseCode = "201", description = "회원가입 성공",
160-
content = @Content(schema = @Schema(implementation = SignUpResponse.class))),
161-
@ApiResponse(responseCode = "400", description = "검증 실패/형식 오류(비밀번호 불일치 등)",
162-
content = @Content(schema = @Schema(implementation = BaseResponse.class))),
163-
@ApiResponse(responseCode = "409", description = "중복(전화/이메일)으로 인한 충돌",
164-
content = @Content(schema = @Schema(implementation = BaseResponse.class)))
165-
})
166125
@PostMapping(value = "/signup/admin", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
167126
public BaseResponse<SignUpResponse> signupAdmin(
168127
@Valid @RequestPart("request")
@@ -187,7 +146,7 @@ public BaseResponse<SignUpResponse> signupAdmin(
187146

188147
// 로그인 (파트너/관리자 공통)
189148
@Operation(
190-
summary = "로그인 API",
149+
summary = "공통 로그인 API",
191150
description = "# v1.0 (2025-08-15)\n" +
192151
"- `application/json`로 호출합니다.\n" +
193152
"- 바디: `LoginRequest(email, password)`.\n" +
@@ -196,47 +155,31 @@ public BaseResponse<SignUpResponse> signupAdmin(
196155
)
197156
@io.swagger.v3.oas.annotations.parameters.RequestBody(
198157
required = true,
199-
content = @Content(schema = @Schema(implementation = LoginRequest.class))
158+
content = @Content(schema = @Schema(implementation = CommonLoginRequest.class))
200159
)
201-
@ApiResponses({
202-
@ApiResponse(responseCode = "200", description = "로그인 성공",
203-
content = @Content(schema = @Schema(implementation = LoginResponse.class))),
204-
@ApiResponse(responseCode = "400", description = "검증 실패/형식 오류",
205-
content = @Content(schema = @Schema(implementation = BaseResponse.class))),
206-
@ApiResponse(responseCode = "401", description = "인증 실패(자격 증명 오류)",
207-
content = @Content(schema = @Schema(implementation = BaseResponse.class)))
208-
})
209-
@PostMapping(value = "/login", consumes = MediaType.APPLICATION_JSON_VALUE)
210-
public BaseResponse<LoginResponse> login(
211-
@RequestBody @Valid LoginRequest request
160+
@PostMapping(value = "/login/common", consumes = MediaType.APPLICATION_JSON_VALUE)
161+
public BaseResponse<LoginResponse> loginCommon(
162+
@RequestBody @Valid CommonLoginRequest request
212163
) {
213-
return BaseResponse.onSuccess(SuccessStatus._OK, loginService.login(request));
164+
return BaseResponse.onSuccess(SuccessStatus._OK, loginService.loginCommon(request));
214165
}
215166

216167

217168
// 학생 로그인
218169
@Operation(
219170
summary = "학생 로그인 API",
220-
description = "# v1.0 (2025-08-15)\n" +
171+
description = "# v1.1 (2025-08-18)\n" +
221172
"- `application/json`로 호출합니다.\n" +
222-
"- 바디: `StudentLoginRequest(email, password)`.\n" +
173+
"- 바디: `바디: `StudentLoginRequest(studentNumber, studentPassword, school)`.\n" +
223174
"- 처리: 자격 증명 검증 후 Access/Refresh 토큰 발급 및 저장.\n" +
224175
"- 성공 시 200(OK)과 토큰/만료시각 반환."
225176
)
226177
@io.swagger.v3.oas.annotations.parameters.RequestBody(
227178
required = true,
228179
content = @Content(schema = @Schema(implementation = StudentLoginRequest.class))
229180
)
230-
@ApiResponses({
231-
@ApiResponse(responseCode = "200", description = "로그인 성공",
232-
content = @Content(schema = @Schema(implementation = LoginResponse.class))),
233-
@ApiResponse(responseCode = "400", description = "검증 실패/형식 오류",
234-
content = @Content(schema = @Schema(implementation = BaseResponse.class))),
235-
@ApiResponse(responseCode = "401", description = "인증 실패(자격 증명 오류)",
236-
content = @Content(schema = @Schema(implementation = BaseResponse.class)))
237-
})
238181
@PostMapping(value = "/login/student", consumes = MediaType.APPLICATION_JSON_VALUE)
239-
public BaseResponse<LoginResponse> login(
182+
public BaseResponse<LoginResponse> loginStudent(
240183
@RequestBody @Valid StudentLoginRequest request
241184
) {
242185
return BaseResponse.onSuccess(SuccessStatus._OK, loginService.loginStudent(request));
@@ -258,16 +201,6 @@ public BaseResponse<LoginResponse> login(
258201
@Parameter(name = "RefreshToken", description = "Refresh Token", required = true,
259202
in = ParameterIn.HEADER, schema = @Schema(type = "string"))
260203
})
261-
@ApiResponses({
262-
@ApiResponse(responseCode = "200", description = "토큰 재발급 성공",
263-
content = @Content(schema = @Schema(implementation = RefreshResponse.class))),
264-
@ApiResponse(responseCode = "400", description = "검증 실패/형식 오류",
265-
content = @Content(schema = @Schema(implementation = BaseResponse.class))),
266-
@ApiResponse(responseCode = "401", description = "인증 실패(토큰 오류/만료)",
267-
content = @Content(schema = @Schema(implementation = BaseResponse.class))),
268-
@ApiResponse(responseCode = "403", description = "접근 거부",
269-
content = @Content(schema = @Schema(implementation = BaseResponse.class)))
270-
})
271204
@PostMapping("/refresh")
272205
public BaseResponse<RefreshResponse> refreshToken(
273206
@RequestHeader("RefreshToken") String refreshToken
@@ -285,20 +218,14 @@ public BaseResponse<RefreshResponse> refreshToken(
285218
"- 처리: Refresh 무효화(선택), Access 블랙리스트 등록.\n" +
286219
"- 성공 시 200(OK)."
287220
)
288-
@ApiResponses({
289-
@ApiResponse(responseCode = "200", description = "로그아웃 성공",
290-
content = @Content(schema = @Schema(implementation = BaseResponse.class))),
291-
@ApiResponse(responseCode = "401", description = "인증 실패(토큰 오류/만료)",
292-
content = @Content(schema = @Schema(implementation = BaseResponse.class)))
293-
})
294221
@DeleteMapping("/logout")
295222
public BaseResponse<Void> logout(
296223
@RequestHeader("Authorization")
297224
@Parameter(name = "Authorization", description = "Access Token. 형식: `Bearer <token>`", required = true,
298225
in = ParameterIn.HEADER, schema = @Schema(type = "string"))
299-
String accessToken
226+
String authorization
300227
) {
301-
logoutService.logout(accessToken);
228+
logoutService.logout(authorization);
302229
return BaseResponse.onSuccess(SuccessStatus._OK, null);
303230
}
304231

src/main/java/com/assu/server/domain/auth/dto/login/LoginRequest.java renamed to src/main/java/com/assu/server/domain/auth/dto/login/CommonLoginRequest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
@AllArgsConstructor
1414
@Builder
1515
@Schema(description = "파트너/관리자 공통 로그인 요청")
16-
public class LoginRequest {
16+
public class CommonLoginRequest {
1717

1818
@Schema(description = "로그인 이메일", example = "user@example.com")
1919
@NotBlank(message = "이메일은 필수입니다.")

src/main/java/com/assu/server/domain/auth/dto/login/StudentLoginRequest.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package com.assu.server.domain.auth.dto.login;
22

3+
import com.assu.server.domain.user.entity.enums.University;
34
import io.swagger.v3.oas.annotations.media.Schema;
45
import jakarta.validation.constraints.NotBlank;
6+
import jakarta.validation.constraints.NotNull;
57
import jakarta.validation.constraints.Size;
68
import lombok.*;
79

@@ -14,14 +16,18 @@
1416
@Schema(description = "학생 로그인 요청")
1517
public class StudentLoginRequest {
1618

17-
@Schema(description = "학번", example = "student@example.com")
19+
@Schema(description = "학번", example = "20001234")
1820
@NotBlank(message = "학번은 필수입니다.")
19-
@Size(max = 10, message = "이메일은 10자를 넘을 수 없습니다.")
21+
@Size(max = 10, message = "학번은 10자를 넘을 수 없습니다.")
2022
private String studentNumber;
2123

2224
@Schema(description = "로그인 비밀번호(평문)", example = "P@ssw0rd!")
2325
@NotBlank(message = "비밀번호는 필수입니다.")
2426
@Size(min = 8, max = 64, message = "비밀번호는 8~64자여야 합니다.")
2527
private String studentPassword;
28+
29+
@Schema(description = "대학 이름", example = "SSU")
30+
@NotNull(message = "대학 이름은 필수입니다.")
31+
private University university;
2632
}
2733

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package com.assu.server.domain.auth.entity;
2+
3+
public enum AuthRealm {
4+
COMMON, SSU
5+
}

src/main/java/com/assu/server/domain/auth/exception/CustomAuthException.java

Lines changed: 0 additions & 30 deletions
This file was deleted.
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package com.assu.server.domain.auth.exception;
2+
3+
import com.assu.server.global.apiPayload.code.BaseErrorCode;
4+
import com.assu.server.global.exception.GeneralException;
5+
import org.springframework.http.HttpStatus;
6+
7+
public class CustomAuthHandler extends GeneralException {
8+
9+
public CustomAuthHandler(BaseErrorCode errorCode) {
10+
super(errorCode);
11+
}
12+
}

0 commit comments

Comments
 (0)