-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: password 일방향 암호화 기능 구현 * feat: cookie 생산-소비 기능 구현 * chore: jwt 관련 의존성 추가 * feat: 토큰 생성 기능 구현 * feat: 로그인 API 구현 * test: 로그인 API 테스트 * feat: 회원가입 API 구현 * test: 회원가입 API 테스트 * feat: 닉네임 생성 기능 구현 * test: 닉네임 생성 기능 테스트 * fix: postconstruct 여러 개라 발생한 에러 해결 * feat: 회원가입 응답값에 랜덤생성한 닉네임 추가 * feat: MemberArgumentResolver 구현 * feat: MemberArgumentResolver 일부 적용 * test: 바뀐 스펙에 맞게 변경 * test: TestConfig 설정해 빈충돌 오류 해결 * test: 공모 작성 API로 MemberArgumentResolver 사용 * feat: 토큰 재발급 API 구현 * test: 토큰 재발급 API 테스트 * test: 토큰 재발급 API 에러 테스트 * feat: MemberArgumentResolver commant에 적용 * feat: MemberArgumentResolver offering에 적용 * feat: MemberArgumentResolver participant에 적용 * refactor: ci값이 일치하지 않을경우 오류메시지 문구 변경 * refactor: 클래스명 일관적으로 변경 * refactor: 직관적인 명명으로 enum 네이밍 변경 * refactor: Custom Exception 적용 * refactor: 컨트롤러 메서드에 접근제어자 명시 * fix: 중복된 enum 값 제거 * test: 바뀐 API 스펙에 맞게 변경 --------- Co-authored-by: fromitive <[email protected]>
- Loading branch information
1 parent
fb8b3e0
commit df16d2e
Showing
58 changed files
with
1,069 additions
and
232 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
### 로그인 API | ||
POST {{base-url}}/auth/login | ||
Content-Type: application/json | ||
|
||
{ | ||
"ci": "dora1234" | ||
} | ||
|
||
### 회원가입 API | ||
POST {{base-url}}/auth/signup | ||
Content-Type: application/json | ||
|
||
{ | ||
"ci": "poke12345678" | ||
} | ||
|
||
### 토큰 재발급 API | ||
POST {{base-url}}/auth/refresh | ||
Content-Type: application/json | ||
|
||
{ | ||
"refreshToken": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxIiwiZXhwIjoxNzI0MTMwODY0fQ.BoN2p--HbWn1zbed2NSZtZm4RumWtVm338sAtxXwEC8" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,2 +1,2 @@ | ||
### 댓글방 목록 조회 API | ||
GET {{base-url}}/comments?member-id=1 | ||
GET {{base-url}}/comments |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,26 @@ | ||
### 공모 상세 조회 API | ||
GET {{base-url}}/offerings/1?member-id=1 | ||
GET {{base-url}}/offerings/1 | ||
|
||
### 공모 목록 조회 API | ||
GET {{base-url}}/offerings?filter=RECENT&search=&last-id=99&page-size=2 | ||
|
||
### 공모 필터 목록 조회 API | ||
GET {{base-url}}/offerings/filters | ||
|
||
### 공모 작성 API | ||
POST {{base-url}}/offerings | ||
Content-Type: application/json | ||
|
||
{ | ||
"title": "공모 제목", | ||
"productUrl": "www.naver.com", | ||
"thumbnailUrl": "www.naver.com/favicon.ico", | ||
"totalCount": 5, | ||
"totalPrice": 10000, | ||
"eachPrice": 2000, | ||
"meetingAddress": "서울특별시 광진구 구의강변로 3길 11", | ||
"meetingAddressDetail": "상세주소아파트", | ||
"meetingAddressDong": "구의동", | ||
"deadline": "2024-10-11T10:00:00", | ||
"description": "내용입니다." | ||
} |
22 changes: 22 additions & 0 deletions
22
backend/src/main/java/com/zzang/chongdae/auth/config/AuthWebMvcConfig.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package com.zzang.chongdae.auth.config; | ||
|
||
import com.zzang.chongdae.auth.controller.CookieConsumer; | ||
import com.zzang.chongdae.auth.service.AuthService; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.context.annotation.Configuration; | ||
import org.springframework.web.method.support.HandlerMethodArgumentResolver; | ||
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | ||
|
||
@RequiredArgsConstructor | ||
@Configuration | ||
public class AuthWebMvcConfig implements WebMvcConfigurer { | ||
|
||
private final AuthService authService; | ||
private final CookieConsumer cookieConsumer; | ||
|
||
@Override | ||
public void addArgumentResolvers(List<HandlerMethodArgumentResolver> resolvers) { | ||
resolvers.add(new MemberArgumentResolver(authService, cookieConsumer)); | ||
} | ||
} |
34 changes: 34 additions & 0 deletions
34
backend/src/main/java/com/zzang/chongdae/auth/config/MemberArgumentResolver.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package com.zzang.chongdae.auth.config; | ||
|
||
import com.zzang.chongdae.auth.controller.CookieConsumer; | ||
import com.zzang.chongdae.auth.service.AuthService; | ||
import com.zzang.chongdae.member.repository.entity.MemberEntity; | ||
import jakarta.servlet.http.HttpServletRequest; | ||
import lombok.AllArgsConstructor; | ||
import org.springframework.core.MethodParameter; | ||
import org.springframework.web.bind.support.WebDataBinderFactory; | ||
import org.springframework.web.context.request.NativeWebRequest; | ||
import org.springframework.web.method.support.HandlerMethodArgumentResolver; | ||
import org.springframework.web.method.support.ModelAndViewContainer; | ||
|
||
@AllArgsConstructor | ||
public class MemberArgumentResolver implements HandlerMethodArgumentResolver { | ||
|
||
private final AuthService authService; | ||
private final CookieConsumer cookieConsumer; | ||
|
||
@Override | ||
public boolean supportsParameter(MethodParameter parameter) { | ||
return parameter.getParameterType().equals(MemberEntity.class); | ||
} | ||
|
||
@Override | ||
public MemberEntity resolveArgument(MethodParameter parameter, | ||
ModelAndViewContainer mavContainer, | ||
NativeWebRequest webRequest, | ||
WebDataBinderFactory binderFactory) { | ||
HttpServletRequest request = (HttpServletRequest) webRequest.getNativeRequest(); | ||
String token = cookieConsumer.getAccessToken(request.getCookies()); | ||
return authService.findMemberByAccessToken(token); | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
backend/src/main/java/com/zzang/chongdae/auth/controller/AuthController.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
package com.zzang.chongdae.auth.controller; | ||
|
||
import com.zzang.chongdae.auth.service.AuthService; | ||
import com.zzang.chongdae.auth.service.dto.LoginRequest; | ||
import com.zzang.chongdae.auth.service.dto.RefreshRequest; | ||
import com.zzang.chongdae.auth.service.dto.SignupRequest; | ||
import com.zzang.chongdae.auth.service.dto.SignupResponse; | ||
import com.zzang.chongdae.auth.service.dto.TokenDto; | ||
import jakarta.servlet.http.Cookie; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import jakarta.validation.Valid; | ||
import java.util.List; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.http.ResponseEntity; | ||
import org.springframework.web.bind.annotation.PostMapping; | ||
import org.springframework.web.bind.annotation.RequestBody; | ||
import org.springframework.web.bind.annotation.RestController; | ||
|
||
@RequiredArgsConstructor | ||
@RestController | ||
public class AuthController { | ||
|
||
private final AuthService authService; | ||
private final CookieProducer cookieExtractor; | ||
private final CookieConsumer cookieConsumer; | ||
|
||
@PostMapping("/auth/login") | ||
public ResponseEntity<Void> login( | ||
@RequestBody @Valid LoginRequest request, HttpServletResponse servletResponse) { | ||
TokenDto tokenDto = authService.login(request); | ||
List<Cookie> cookies = cookieExtractor.extractAuthCookies(tokenDto); | ||
cookieConsumer.addCookies(servletResponse, cookies); | ||
return ResponseEntity.ok().build(); | ||
} | ||
|
||
@PostMapping("/auth/signup") | ||
public ResponseEntity<SignupResponse> signup( | ||
@RequestBody SignupRequest request) { | ||
SignupResponse response = authService.signup(request); | ||
return ResponseEntity.ok(response); | ||
} | ||
|
||
@PostMapping("/auth/refresh") | ||
public ResponseEntity<Void> refresh( | ||
@RequestBody RefreshRequest request, HttpServletResponse servletResponse) { | ||
TokenDto tokenDto = authService.refresh(request); | ||
List<Cookie> cookies = cookieExtractor.extractAuthCookies(tokenDto); | ||
cookieConsumer.addCookies(servletResponse, cookies); | ||
return ResponseEntity.ok().build(); | ||
} | ||
} |
37 changes: 37 additions & 0 deletions
37
backend/src/main/java/com/zzang/chongdae/auth/controller/CookieConsumer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
package com.zzang.chongdae.auth.controller; | ||
|
||
import com.zzang.chongdae.auth.exception.AuthErrorCode; | ||
import com.zzang.chongdae.global.exception.MarketException; | ||
import jakarta.servlet.http.Cookie; | ||
import jakarta.servlet.http.HttpServletResponse; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class CookieConsumer { | ||
|
||
private static final String ACCESS_TOKEN_COOKIE_NAME = "access_token"; | ||
private static final String REFRESH_TOKEN_COOKIE_NAME = "refresh_token"; | ||
|
||
public void addCookies(HttpServletResponse servletResponse, List<Cookie> cookies) { | ||
for (Cookie cookie : cookies) { | ||
servletResponse.addCookie(cookie); | ||
} | ||
} | ||
|
||
public String getAccessToken(Cookie[] cookies) { | ||
return getTokenByCookieName(ACCESS_TOKEN_COOKIE_NAME, cookies); | ||
} | ||
|
||
private String getTokenByCookieName(String cookieName, Cookie[] cookies) { | ||
if (cookies == null) { | ||
throw new MarketException(AuthErrorCode.INVALID_TOKEN); | ||
} | ||
return Arrays.stream(cookies) | ||
.filter(cookie -> cookie.getName().equals(cookieName)) | ||
.findFirst() | ||
.map(Cookie::getValue) | ||
.orElseThrow(() -> new MarketException(AuthErrorCode.INVALID_TOKEN)); | ||
} | ||
} |
28 changes: 28 additions & 0 deletions
28
backend/src/main/java/com/zzang/chongdae/auth/controller/CookieProducer.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
package com.zzang.chongdae.auth.controller; | ||
|
||
import com.zzang.chongdae.auth.service.dto.TokenDto; | ||
import jakarta.servlet.http.Cookie; | ||
import java.util.ArrayList; | ||
import java.util.List; | ||
import org.springframework.stereotype.Component; | ||
|
||
@Component | ||
public class CookieProducer { | ||
|
||
private static final String ACCESS_TOKEN_COOKIE_NAME = "access_token"; | ||
private static final String REFRESH_TOKEN_COOKIE_NAME = "refresh_token"; | ||
|
||
public List<Cookie> extractAuthCookies(TokenDto tokenDto) { | ||
List<Cookie> cookies = new ArrayList<>(); | ||
cookies.add(createCookie(ACCESS_TOKEN_COOKIE_NAME, tokenDto.accessToken())); | ||
cookies.add(createCookie(REFRESH_TOKEN_COOKIE_NAME, tokenDto.refreshToken())); | ||
return cookies; | ||
} | ||
|
||
private Cookie createCookie(String tokenName, String token) { | ||
Cookie cookie = new Cookie(tokenName, token); | ||
cookie.setHttpOnly(true); | ||
cookie.setPath("/"); | ||
return cookie; | ||
} | ||
} |
25 changes: 25 additions & 0 deletions
25
backend/src/main/java/com/zzang/chongdae/auth/exception/AuthErrorCode.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
package com.zzang.chongdae.auth.exception; | ||
|
||
import com.zzang.chongdae.global.exception.ErrorMessage; | ||
import com.zzang.chongdae.global.exception.ErrorResponse; | ||
import lombok.AllArgsConstructor; | ||
import lombok.Getter; | ||
import org.springframework.http.HttpStatus; | ||
|
||
@Getter | ||
@AllArgsConstructor | ||
public enum AuthErrorCode implements ErrorResponse { | ||
|
||
INVALID_TOKEN(HttpStatus.UNAUTHORIZED, "유효하지 않은 토큰입니다."), | ||
EXPIRED_TOKEN(HttpStatus.UNAUTHORIZED, "만료된 토큰입니다."), | ||
INVALID_PASSWORD(HttpStatus.NOT_FOUND, "가입하지 않은 회원입니다."), | ||
DUPLICATED_MEMBER(HttpStatus.CONFLICT, "이미 가입한 회원입니다."); | ||
|
||
private final HttpStatus status; | ||
private final String message; | ||
|
||
@Override | ||
public ErrorMessage getErrorMessage() { | ||
return new ErrorMessage(this.message); | ||
} | ||
} |
55 changes: 55 additions & 0 deletions
55
backend/src/main/java/com/zzang/chongdae/auth/service/AuthService.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
package com.zzang.chongdae.auth.service; | ||
|
||
import com.zzang.chongdae.auth.exception.AuthErrorCode; | ||
import com.zzang.chongdae.auth.service.dto.LoginRequest; | ||
import com.zzang.chongdae.auth.service.dto.RefreshRequest; | ||
import com.zzang.chongdae.auth.service.dto.SignupRequest; | ||
import com.zzang.chongdae.auth.service.dto.SignupResponse; | ||
import com.zzang.chongdae.auth.service.dto.TokenDto; | ||
import com.zzang.chongdae.global.exception.MarketException; | ||
import com.zzang.chongdae.member.exception.MemberErrorCode; | ||
import com.zzang.chongdae.member.repository.MemberRepository; | ||
import com.zzang.chongdae.member.repository.entity.MemberEntity; | ||
import com.zzang.chongdae.member.service.NicknameGenerator; | ||
import lombok.RequiredArgsConstructor; | ||
import org.springframework.stereotype.Service; | ||
import org.springframework.transaction.annotation.Transactional; | ||
|
||
@RequiredArgsConstructor | ||
@Service | ||
public class AuthService { | ||
|
||
private final MemberRepository memberRepository; | ||
private final PasswordEncoder passwordEncoder; | ||
private final JwtTokenProvider jwtTokenProvider; | ||
private final NicknameGenerator nickNameGenerator; | ||
|
||
public TokenDto login(LoginRequest request) { | ||
String password = passwordEncoder.encode(request.ci()); | ||
MemberEntity member = memberRepository.findByPassword(password) | ||
.orElseThrow(() -> new MarketException(AuthErrorCode.INVALID_PASSWORD)); | ||
return jwtTokenProvider.createAuthToken(member.getId().toString()); | ||
} | ||
|
||
@Transactional | ||
public SignupResponse signup(SignupRequest request) { | ||
String password = passwordEncoder.encode(request.ci()); | ||
if (memberRepository.existsByPassword(password)) { | ||
throw new MarketException(AuthErrorCode.DUPLICATED_MEMBER); | ||
} | ||
MemberEntity member = new MemberEntity(nickNameGenerator.generate(), password); | ||
MemberEntity savedMember = memberRepository.save(member); | ||
return new SignupResponse(savedMember); | ||
} | ||
|
||
public TokenDto refresh(RefreshRequest request) { | ||
Long memberId = jwtTokenProvider.getMemberIdByRefreshToken(request.refreshToken()); | ||
return jwtTokenProvider.createAuthToken(memberId.toString()); | ||
} | ||
|
||
public MemberEntity findMemberByAccessToken(String token) { | ||
Long memberId = jwtTokenProvider.getMemberIdByAccessToken(token); | ||
return memberRepository.findById(memberId) | ||
.orElseThrow(() -> new MarketException(MemberErrorCode.NOT_FOUND)); | ||
} | ||
} |
Oops, something went wrong.