-
Notifications
You must be signed in to change notification settings - Fork 0
[Gibeom] Week8 미션 #92
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
6c6ab14
46cda5e
067cc43
b0f7937
7cd6e5f
e61fb7f
ed32523
04c0f1d
c9f6174
f4553da
d3309f9
1cc4127
54bdcd1
eb834fd
0cf5246
eb99d06
a82319d
acbca07
1d11a2d
0fda854
8bf2421
a4c5eb1
719aaab
db958b5
558d691
886eab9
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
This file was deleted.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,42 @@ | ||
| - Spring Security가 무엇인가? | ||
|
|
||
| 스프링 기반 애플리케이션의 보안을 담당하는 강력하고 포괄적인 하위 프레임워크 | ||
|
|
||
| 복잡한 보안 로직을 직접 구현할 필요 없이 표준화된 필터 기반의 설정을 통해 시스템을 안전하게 보호한다. | ||
|
|
||
| - 인증(Authentication)vs 인가(Authorization) | ||
|
|
||
| 비슷해보이지만 서로 다른 개념이다. | ||
|
|
||
| 인증 (Authentication) | ||
|
|
||
| - 본인확인 절차 | ||
| - 사용자가 자신이 주장하는 사람이 맞는지 확인하는 과정 | ||
|
|
||
| 인가 (Authorization) | ||
|
|
||
| - 권한확인 절차 | ||
| - 인증된 사용자가 특정 리소스에 접근할 수 있는 권한이 있는지 확인하는 과정 | ||
|
|
||
| - Stateful vs Stateless | ||
|
|
||
| 논점 : 서버가 클라이언트의 세션 정보를 기억하는가? | ||
|
|
||
| Stateful(상태유지) : 세션 정보를 기억함 | ||
|
|
||
| Stateless(토큰 기반) : 서버가 상태를 유지하지 않으므로 요청에 포함된 토큰(JWT)로 검증 | ||
|
|
||
| | 구분 | Stateful | Stateless | | ||
| | --- | --- | --- | | ||
| | 특징 | 서버가 세션 저장소에 로그인 상태 유지 | 서버가 상태를 유지하지 않음, 요청에 포함된 토큰으로 검증 | | ||
| | 인증방식 | JSESSION쿠키를 통해 서버 메모리/DB의 세션 조회 | 매 요청시 HTTP헤더에 토큰을 담아서 전송 (Authorization:Bearer<token>) | | ||
| | 서버 확장 | 세션 불일치 문제 발생 가능 | 각 요청이 독립적이므로 서버 증설에 유리 | | ||
| | 메모리 및 비용 | 동시접속자가 많을수록 서버 세션 메모리 소비 증가 | 토큰 검증 연산이 필요하며, 서버 메모리 사용량은 적음 | | ||
| | 주요 활용처 | 전톤적인 웹 애플리케이션 | REST API, 모바일 앱, MSA | | ||
|
|
||
| 서버 확장 방법 | ||
|
|
||
| - Scale-up : 단일 서버 성능 향상 | ||
| - Scale-out : 서버의 개수를 늘리기 | ||
| - 로드밸런서 : 서버 부하를 분산시키는 H/W, S/W | ||
| - 클라이언트와 서버Pool 사이에 위치해 서버의 부하를 분산시키는 하드웨어나 S/W | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,54 +1,77 @@ | ||
| package com.example.umc10th.domain.member.controller; | ||
|
|
||
| import com.example.umc10th.domain.member.dto.MemberReqDTO; | ||
| import com.example.umc10th.domain.member.dto.MemberResDTO; | ||
| import com.example.umc10th.domain.member.enums.MissionStatus; | ||
| import com.example.umc10th.domain.member.service.MemberService; | ||
| import com.example.umc10th.domain.mission.dto.MissionResDTO; | ||
| import com.example.umc10th.global.apiPayload.ApiResponse; | ||
| import com.example.umc10th.global.apiPayload.code.BaseSuccessCode; | ||
| import com.example.umc10th.domain.member.exception.code.MemberSuccessCode; | ||
| import com.example.umc10th.global.entity.AuthMember; | ||
| import jakarta.validation.Valid; | ||
| import lombok.RequiredArgsConstructor; | ||
| import org.springframework.http.ResponseEntity; | ||
| import org.springframework.security.core.annotation.AuthenticationPrincipal; | ||
| import org.springframework.web.bind.annotation.*; | ||
|
|
||
| import java.util.List; | ||
|
|
||
| @RestController | ||
| @RequiredArgsConstructor | ||
| @RequestMapping("/api/v1/members") | ||
| @RequestMapping("/api") | ||
| public class MemberController { | ||
|
|
||
| private final MemberService memberService; | ||
| //마이페이지 | ||
| @GetMapping("/me") | ||
| public ApiResponse<MemberResDTO.GetInfo> getInfo( | ||
| @GetMapping("/v1/members/me") | ||
| public ResponseEntity<ApiResponse<MemberResDTO.GetInfo>> getInfo( | ||
| @AuthenticationPrincipal Long memberId | ||
| ){ | ||
| BaseSuccessCode code = MemberSuccessCode.OK; | ||
| return ApiResponse.onSuccess(code, memberService.getInfo(memberId)); | ||
| MemberResDTO.GetInfo result = memberService.getInfo(memberId); | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
이번 변경에서 Useful? React with 👍 / 👎. |
||
| return ResponseEntity | ||
| .status(code.getStatus()) | ||
| .body(ApiResponse.onSuccess(code, result)); | ||
| } | ||
|
|
||
| // 홈화면 | ||
| @GetMapping("/home") | ||
| public ApiResponse<MemberResDTO.HomeResultDto> getHome( | ||
| @AuthenticationPrincipal Long memberId, | ||
| @GetMapping("/v1/members/home") | ||
| public ResponseEntity<ApiResponse<MemberResDTO.HomeResultDto>> getHome( | ||
| @AuthenticationPrincipal AuthMember authMember, | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
| @RequestParam(defaultValue = "0") int page | ||
| ){ | ||
| BaseSuccessCode code = MemberSuccessCode.OK; | ||
| return ApiResponse.onSuccess(code, memberService.getHome(memberId, page)); | ||
| MemberResDTO.HomeResultDto result = memberService.getHome(authMember.getMember().getId(), page); | ||
| return ResponseEntity | ||
| .status(MemberSuccessCode.OK.getStatus()) | ||
| .body(ApiResponse.onSuccess(MemberSuccessCode.OK, result)); | ||
| } | ||
|
|
||
| // 진행중/완료 미션 목록 조회 | ||
| @GetMapping("/missions") | ||
| public ApiResponse<List<MissionResDTO.MissionDto>> getMissionsByStatus( | ||
| @GetMapping("/v1/members/missions") | ||
| public ResponseEntity<ApiResponse<List<MissionResDTO.MissionDto>>> getMissionsByStatus( | ||
| @AuthenticationPrincipal Long memberId, | ||
| @RequestParam MissionStatus status, | ||
| @RequestParam Integer pageSize, | ||
| @RequestParam Integer pageNum, | ||
| @RequestParam (required = false) String sort | ||
| ){ | ||
| BaseSuccessCode code = MemberSuccessCode.OK; | ||
| return ApiResponse.onSuccess(code, memberService.getMissionsByStatus(memberId, status, pageSize, pageNum, sort)); | ||
| List<MissionResDTO.MissionDto> result = memberService.getMissionsByStatus(memberId, status, pageSize, pageNum, sort); | ||
| return ResponseEntity | ||
| .status(code.getStatus()) | ||
| .body(ApiResponse.onSuccess(code, result)); | ||
| } | ||
|
|
||
|
|
||
| //회원가입 | ||
| @PostMapping("/auth/sign-up") | ||
| public ResponseEntity<ApiResponse<Void>> signUp( | ||
| @RequestBody @Valid MemberReqDTO.SignUp req | ||
| ){ | ||
| memberService.signUp(req); | ||
| return ResponseEntity | ||
| .status(MemberSuccessCode.CREATED.getStatus()) | ||
| .body(ApiResponse.onSuccess(MemberSuccessCode.CREATED, null)); | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,5 +1,24 @@ | ||
| package com.example.umc10th.domain.member.dto; | ||
|
|
||
| import com.example.umc10th.domain.member.enums.Gender; | ||
| import jakarta.validation.constraints.Email; | ||
| import jakarta.validation.constraints.NotBlank; | ||
| import lombok.Getter; | ||
|
|
||
| public class MemberReqDTO { | ||
|
|
||
| public record SignUp ( | ||
| @NotBlank | ||
| String name, | ||
| @NotBlank | ||
| String nickname, | ||
| @Email @NotBlank | ||
| String email, | ||
| @NotBlank | ||
| String password, | ||
| @NotBlank | ||
| String phoneNumber, | ||
| Gender gender | ||
| ){} | ||
|
|
||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -12,7 +12,15 @@ public enum MemberErrorCode implements BaseErrorCode { | |
| "COMMON404_1", | ||
| "해당 사용자를 찾을 수 없습니다." | ||
| ), | ||
| EMAIL_DUPLICATED(HttpStatus.NOT_FOUND, | ||
| "COMMON404_2", | ||
| "해당 사용자를 찾을 수 없습니다." | ||
|
Comment on lines
+15
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Useful? React with 👍 / 👎. |
||
| ), | ||
| NICKNAME_DUPLICATED(HttpStatus.CONFLICT, | ||
| "COMMON409_2", | ||
| "이미 존재하는 닉네임입니다." | ||
|
|
||
| ) | ||
| ; | ||
| private final HttpStatus status; | ||
| private final String code; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stateful/Stateless 비교 표를 작성한 점이 좋습니다. 다만 Markdown 표 구분선의 들여쓰기가 맞지 않아 표가 깨질 수 있으며, 현재 코드의
formLogin은 Stateful 세션 방식에 가깝습니다. 표 아래에formLogin,SecurityContext,JSESSIONID, JWT 방식의 차이를 현재 구현과 연결해 추가 정리하는 것을 권장합니다.