๋ค์ด๋ฒ ํด๋ผ์ฐ๋ ๋ฐ๋ธ์ต์ค 3๊ธฐ 4์กฐ - ์ธ๋ฏธ ํ๋ก์ ํธ
๊ฐ๋ฐ๊ธฐ๊ฐ: 2023.12.04 - 2023.12.26
- <๋ํผ์ ๋จน๋๋ค>๋ ์์ทจ์๋ค์ด ์๋ก ๋ ์ํผ๋ฅผ ์ ๊ณตํ๊ณ ๊ณต์ ํ๊ณ , ์ค๊ณ ๊ฑฐ๋ ๊ด๋ จ ์ปค๋ฎค๋ํฐ ํ๋์ ํ ์ ์๋๋ก ์ ์ํ ์ปค๋ฎค๋ํฐ ๊ธฐ๋ฐ ํ๋ก์ ํธ์ ๋๋ค. ๋ฐ๋ธ์ต์ค ์์ ์์ ํ์ตํ Maven Project๋ฅผ ๋ณต์ตํ๋ฉฐ ํ์ฉํ์์ต๋๋ค.
์๋ Swiper ๋ฅผ ์ฌ์ฉํ์ฌ ๋ ์ํผ, ์ปค๋ฎค๋ํฐ, ๋ฒผ๋ฃฉ์์ฅ์ ์ด๋ฏธ์ง๋ก ์๊ฐ. ํด๋ฆญ ์ ํด๋น ๋งํฌ ์ด๋.
| ๋ฉ์ธํ๋ฉด |
|
ํ์๊ฐ์ ์ ์ด๋ฉ์ผ ์ค๋ณต ์ฒดํฌ, ๋๋ค์ ์ค๋ณต ์ฒดํฌ ๊ธฐ๋ฅ์ ํ๋ API ์ฌ์ฉ. ๋น๋ฐ๋ฒํธ ์ผ์น ํ์ธ ๋ก์ง ์ฌ์ฉ.
API ์ฝ๋ ์์ธํ ๋ณด๊ธฐ
//ํ์๊ฐ์
์ค๋ณต ์ด๋ฉ์ผ ์ฒดํฌ ๋ก์ง (API)
@PostMapping("/duplicatedNickNameCheck")
public ResponseEntity<?> duplicatedNickNameCheck(@RequestBody MemberDto memberDto) {
int result = memberService.duplicatedNickNameCheck(memberDto);
HashMap<String,String> resultMap = new HashMap<>();
//์ค๋ณต ํ์์ด ์์ ๊ฒฝ์ฐ
if(result == 1){
resultMap.put("status","500");
resultMap.put("message","์ด๋ฏธ ๊ฐ์
๋ ๋๋ค์์ด ์กด์ฌํฉ๋๋ค!");
}
//์ค๋ณต ํ์์ด ์์ ๊ฒฝ์ฐ
else {
resultMap.put("status","200");
resultMap.put("message","์ฌ์ฉ ๊ฐ๋ฅํ ๋๋ค์ ์
๋๋ค.");
}| ํ์๊ฐ์ |
|
์ธ์ ์ฟ ํค์ ๋ํ ์ดํด๋ฅผ ํตํด ๋ก๊ทธ์ธ์ ํด์ผ ์ปค๋ฎค๋ํฐ ๋ฑ๋ก๊ธฐ๋ฅ์ ์ฌ์ฉํ ์ ์๋๋ก ๊ตฌํ.
| ๋ก๊ทธ์ธ/๋ก๊ทธ์์ ๊ธฐ๋ฅ |
|
@ControllerAdvice์ @ExceptionHandler๋ฅผ ์ฌ์ฉํ ์ ์ญ ์์ธ ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์ ์.
๊ด๋ จ ์ฝ๋์ ์ค๋ช ์์ธํ ๋ณด๊ธฐ
package semi.controller.advice;
import com.mysql.cj.util.StringUtils;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;
import semi.customException.NotLoggedInException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(semi.customException.NotLoggedInException.class)
public String handleNotLoggedInException(NotLoggedInException ex, HttpSession httpSession) {
httpSession.setAttribute("redirectUrl", getRequestUri());
return "redirect:/member/login";
}
private String getRequestUri() {
RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes();
HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();
String requestUri = request.getRequestURI();
String contextPath = request.getContextPath();
if (!StringUtils.isNullOrEmpty(contextPath)) {
return requestUri.substring(contextPath.length());
}
else {
return requestUri;
}
}
}-
@ControllerAdvice์ @ExceptionHandler ๋ถ๋ถ ์ด ๋ถ๋ถ์ ์ด์ ์ค๋ช ๊ณผ ๋์ผํ๊ฒ ์ ์ญ ์์ธ ์ฒ๋ฆฌ๊ธฐ๋ฅผ ์ค์ ํฉ๋๋ค. @ExceptionHandler(semi.customException.NotLoggedInException.class)์ ๋ก๊ทธ์ธ๋์ง ์์ ์ํ์์ ๋ฐ์ํ๋ NotLoggedInException์ ์ฒ๋ฆฌํ๋ ์ญํ ์ ํ๋ฉฐ, ๋ก๊ทธ์ธ ํ์ด์ง๋ก ๋ฆฌ๋ค์ด๋ ํธํ๋ ๋ฐฉ์์ผ๋ก ์์ธ๋ฅผ ์ฒ๋ฆฌํฉ๋๋ค. ์์ธ ๋ฐ์ ์, ์ฌ์ฉ์๊ฐ ๋ฐฉ๋ฌธํ๋ ค๋ ํ์ด์ง์ URL์ ์ธ์ ์ ์ ์ฅํ๊ณ , ๋์ค์ ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ ํ ์๋ ๊ฐ๋ ค๋ ํ์ด์ง๋ก ๋ค์ ์ด๋์ํค๋ ๋ก์ง์ ๋๋ค.
-
getRequestUri() ๋ฉ์๋ ๋ถ์ ์ด ๋ฉ์๋๋ ํ์ฌ ์์ฒญ๋ URI๋ฅผ ๊ฐ์ ธ์ค๋ ์ญํ ์ ํฉ๋๋ค. ์ด๋ฅผ ํตํด ์ฌ์ฉ์๊ฐ ๋ก๊ทธ์ธํ์ง ์์ ์ํ์์ ์ด๋ค ํ์ด์ง์ ์ ๊ทผํ๋์ง๋ฅผ ํ์ธํ ์ ์์ต๋๋ค.
-
- RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes(); Spring์ RequestContextHolder๋ฅผ ์ฌ์ฉํ์ฌ ํ์ฌ ์์ฒญ๊ณผ ๊ด๋ จ๋ ์์ฑ์ ๊ฐ์ ธ์ต๋๋ค. ์ด๋ฅผ ํตํด ํ์ฌ HTTP ์์ฒญ ๊ฐ์ฒด์ ์ ๊ทผํ ์ ์๊ฒ ๋ฉ๋๋ค.
-
- HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); ServletRequestAttributes ๊ฐ์ฒด๋ก ์บ์คํ ํ ํ, HttpServletRequest ๊ฐ์ฒด๋ฅผ ์ป์ต๋๋ค. ์ด ๊ฐ์ฒด๋ ํ์ฌ HTTP ์์ฒญ์ ๋ํ ์ ๋ณด๋ฅผ ๋ด๊ณ ์์ผ๋ฉฐ, ์ด๋ฅผ ํตํด URI๋ฅผ ์ป์ ์ ์์ต๋๋ค.
-
- String requestUri = request.getRequestURI(); getRequestURI()๋ ํ์ฌ ์์ฒญ๋ URI ๊ฒฝ๋ก๋ฅผ ๋ฐํํฉ๋๋ค. ์๋ฅผ ๋ค์ด, /member/profile ๊ฐ์ URL ๊ฒฝ๋ก๋ฅผ ์ป์ ์ ์์ต๋๋ค.
-
- String contextPath = request.getContextPath(); getContextPath()๋ ์ ํ๋ฆฌ์ผ์ด์ ์ ์ปจํ ์คํธ ๊ฒฝ๋ก๋ฅผ ๋ฐํํฉ๋๋ค. ์๋ฅผ ๋ค์ด, ์ ํ๋ฆฌ์ผ์ด์ ์ด /app์ด๋ผ๋ ๊ฒฝ๋ก์์ ์คํ ์ค์ด๋ฉด /app์ด ์ปจํ ์คํธ ๊ฒฝ๋ก๊ฐ ๋ฉ๋๋ค.
-
- if (!StringUtils.isNullOrEmpty(contextPath)) { ... } contextPath๊ฐ ๋น ๋ฌธ์์ด์ด ์๋๊ฑฐ๋ null์ด ์๋๋ฉด, requestUri์์ ์ปจํ ์คํธ ๊ฒฝ๋ก๋ฅผ ์ ๊ฑฐํ ํ ๋ฐํํฉ๋๋ค. ์๋ฅผ ๋ค์ด, requestUri๊ฐ /app/member/profile์ด๊ณ contextPath๊ฐ /app์ธ ๊ฒฝ์ฐ, ์ด ๋ฉ์๋๋ /member/profile์ ๋ฐํํฉ๋๋ค. contextPath๊ฐ ์์ ๊ฒฝ์ฐ, ์ฆ, ๋ฃจํธ์์ ์คํ ์ค์ด๋ฉด requestUri๋ฅผ ๊ทธ๋๋ก ๋ฐํํฉ๋๋ค.
package ArgumentResolver;
import annotation.Login;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
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;
import semi.customException.NotLoggedInException;
import semi.dto.MemberDto;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import static semi.config.MemberConstants.LOGIN_MEMBER_DTO;
@Component
public class LoginMemberArgumentResolver implements HandlerMethodArgumentResolver {
@Override
public boolean supportsParameter(MethodParameter methodParameter) {
boolean hasLoginAnnotation = methodParameter.hasParameterAnnotation(Login.class);
boolean hasMemberType = MemberDto.class.isAssignableFrom(methodParameter.getParameterType());
return hasLoginAnnotation && hasMemberType;
}
@Override
public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
HttpServletRequest request = (HttpServletRequest) nativeWebRequest.getNativeRequest();
HttpSession session = request.getSession(false);
if (session == null) throw new NotLoggedInException();
Object loginSession = session.getAttribute(LOGIN_MEMBER_DTO);
if (loginSession == null) throw new NotLoggedInException();
return session.getAttribute(LOGIN_MEMBER_DTO);
}
}- supportsParameter(MethodParameter methodParameter)
- ์ญํ : ์ด ๋ฉ์๋๋ ์ฃผ์ด์ง ๋ฉ์๋ ํ๋ผ๋ฏธํฐ๊ฐ ์ฒ๋ฆฌ ๊ฐ๋ฅํ ํ๋ผ๋ฏธํฐ์ธ์ง๋ฅผ ํ์ธํฉ๋๋ค.
- hasLoginAnnotation: ํ๋ผ๋ฏธํฐ์ @Login ์ด๋ ธํ ์ด์ ์ด ๋ถ์ด ์๋์ง ํ์ธํฉ๋๋ค. ์ด ์ด๋ ธํ ์ด์ ์ด ๋ถ์ ํ๋ผ๋ฏธํฐ๋ง ์ด resolver๊ฐ ์ฒ๋ฆฌํฉ๋๋ค.
- hasMemberType: ํ๋ผ๋ฏธํฐ ํ์ ์ด MemberDto ํด๋์ค ๋๋ ๊ทธ ํ์ ํด๋์ค์ธ์ง ํ์ธํฉ๋๋ค. ์ฆ, MemberDto ํ์ ์ ๊ฐ์ฒด๋ง ์ฒ๋ฆฌ ๋์์ผ๋ก ํฉ๋๋ค.
- ๊ฒฐ๊ณผ: ๋ ์กฐ๊ฑด์ด ๋ชจ๋ ์ฐธ์ด๋ฉด true๋ฅผ ๋ฐํํ์ฌ ํด๋น ํ๋ผ๋ฏธํฐ๋ฅผ ์ฒ๋ฆฌํ ์ ์์์ ๋ํ๋ ๋๋ค.
- resolveArgument(...)
-
์ญํ : ์ด ๋ฉ์๋๋ ์ค์ ๋ก ๋ฉ์๋ ํ๋ผ๋ฏธํฐ์ ๊ฐ์ ๋ฐ์ธ๋ฉํฉ๋๋ค. @Login ์ด๋ ธํ ์ด์ ์ด ๋ถ์ MemberDto ํ๋ผ๋ฏธํฐ์ ์ธ์ ์ ๋ณด๋ฅผ ์ค์ ํ๋ ์ญํ ์ ํฉ๋๋ค.
-
ํ๋ฆ:
-
HttpServletRequest request = (HttpServletRequest) nativeWebRequest.getNativeRequest(); NativeWebRequest์์ HTTP ์์ฒญ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ต๋๋ค.
-
HttpSession session = request.getSession(false); ํ์ฌ ์์ฒญ์ ๋ํ ์ธ์ ์ ๊ฐ์ ธ์ต๋๋ค. false๋ก ์ค์ ํ๊ธฐ ๋๋ฌธ์ ์ธ์ ์ด ์์ผ๋ฉด ์๋ก ์์ฑํ์ง ์๊ณ null์ ๋ฐํํฉ๋๋ค. ์ธ์ ์ด ์กด์ฌํ์ง ์์ผ๋ฉด NotLoggedInException์ ๋ฐ์์ํต๋๋ค.
-
Object loginSession = session.getAttribute(LOGIN_MEMBER_DTO); ์ธ์ ์์ LOGIN_MEMBER_DTO๋ผ๋ ์ด๋ฆ์ผ๋ก ์ ์ฅ๋ ๊ฐ์ฒด๋ฅผ ๊ฐ์ ธ์ต๋๋ค. ์ด๋ ์๋ง๋ ๋ก๊ทธ์ธ๋ ์ฌ์ฉ์์ ์ ๋ณด๋ฅผ ๋ด๊ณ ์๋ MemberDto ๊ฐ์ฒด์ผ ๊ฒ์ ๋๋ค. ์ธ์ ์ ํด๋น ์ ๋ณด๊ฐ ์์ผ๋ฉด NotLoggedInException์ ๋ฐ์์ํต๋๋ค.
-
return session.getAttribute(LOGIN_MEMBER_DTO); ์ธ์ ์์ ๊ฐ์ ธ์จ LOGIN_MEMBER_DTO ๊ฐ์ฒด๋ฅผ ๋ฐํํ์ฌ, ๋ฉ์๋ ํ๋ผ๋ฏธํฐ๋ก ์๋์ผ๋ก ์ ๋ฌ๋๋๋ก ํฉ๋๋ค.
-
| ๋ก๊ทธ์ธ ํ๋ฉด์ผ๋ก ๋ฆฌํด |
|
- ์ ์ ์ด์
- ์ฌ์ฉ์ ์ ์ฅ์์ ์ ๋ณด๋ฅผ ์ ๋ ฅํ๊ณ ์์ ํ๋ ๊ฒ๋ณด๋ค ๋ฐ๋ก ๊ฒฐ๊ณผ๋ฅผ ๋ณด์ฌ์ค์ผ๋ก ์ฌ์ฉ์ ํธ์์ฑ๊ณผ ์ ํํ ๋ฐ์ดํฐ๋ฅผ ์์งํ๊ธฐ ์ํด์ ๊ฐ์ ํด์ผ ํ ๋ถ๋ถ์ด๋ผ๊ณ ์๊ฐํฉ๋๋ค.
- ๊ฐ์ ๋ฐฉํฅ
- ์ ํจ์ฑ ๊ฒ์ฌ๊ฐ ๋ชจ๋ ํต๊ณผ๋ ๊ฒฝ์ฐ ๋ค์ ๋ฒํผ์ด ํ์ฑํ๋๋ฉฐ, ๋ฒํผ์ ํด๋ฆญํ๋ฉด ํ๋กํ ์ค์ ํ๋ฉด์ด ๋ํ๋๋๋ก ์ ์ฉํด๋ณด๊ณ ์ถ์ต๋๋ค.
- ์ถํ ๊ด๋ จ ์ง์ ์ต๋์ ์ํ ํค์๋
- html, javascript
- ์ ์ ์ด์
- ๋น๋ฐ๋ฒํธ๋ฅผ ์ํธํ๋ฅผ ๊ณ ๋ คํ์ง ์๊ณ DB์ ์ ์ฅํ์ฌ ๋ฐ์ดํฐ ์ ์ถ์ ์ํ๊ณผ ์ฌ์ฉ์์ ์ ๋ขฐ๋๊ฐ ๋จ์ด์ง๊ฒ ๋๋ ์์ฌ์์ด ๋จ์์ต๋๋ค.
- ๊ฐ์ ๋ฐฉํฅ
- SHA-256, bcrypt, PBKDF2, Argon2 ๋ฑ๊ณผ ๊ฐ์ ์์ ํ ํด์ ํจ์๋ฅผ ์ฌ์ฉํ์ฌ ๋น๋ฐ๋ฒํธ๋ฅผ ํด์ํํด ์ ์ฅํฉ๋๋ค.
- ์ํธ, ํํผ๋ฅผ ์ถ๊ฐํ๊ณ ์ฌ์ฉํ์ฌ ๋์ฑ ์์ ํ ์ฌ์ฉ์ ์ธ์ฆ ์์คํ ์ ๊ตฌ์ถํ ์ ์์ต๋๋ค.
- ์ถํ ๊ด๋ จ ์ง์ ์ต๋์ ์ํ ํค์๋
- ํด์ ํจ์ ์ฌ์ฉ, ์ํธ, ํํผ
-
๊ฐ์ธ Mini ํ๋ก์ ํธ๋ง ๊ตฌํํ๋ค๊ฐ ์ฒ์์ผ๋ก ํด๋ณธ ํ ํ๋ก์ ํธ์์ต๋๋ค. ์ฐจ๊ทผ์ฐจ๊ทผ ๊ธฐ์ด๋ถํฐ ์๋๋ค๋ ๋ง์๊ฐ์ง์ผ๋ก ์ ๋ฐ์ ์ธ ํ๋ฉด ๊ตฌ์ฑ๊ณผ ๋ก๊ทธ์ธ์ ๋ด๋นํ์์ต๋๋ค.
-
์ํต๊ณผ ํผ๋๋ฐฑ์ ํตํด ํ์๋ค๊ณผ ์๊ฒฌ์ ์กฐ์จํ๋ ๊ฒ์ ์๋ก์ ์ง์์ ๋์ฑ ๊ฐ์น์๊ฒ ๋ง๋ค์ด์ฃผ๋ ๊ณ๊ธฐ๊ฐ ๋์ด ์ข์ ๊ฒฐ๊ณผ๋ฅผ ์ด๋์ด๋ผ ์ ์์์ต๋๋ค.
-
๊ตฌํ ์ค ๋ฐ์ํ ์ค๋ฅ์ ์ค์๋ฅผ ๊ธฐ๋กํ๊ณ , ์ด๋ฅผ ํตํด ๋ฌธ์ ๋ฅผ ๋ณด์ํ๋ ๊ฒ์ ์ค์์ฑ์ ์๊ฒ ๋์์ต๋๋ค. ์ด๋ฌํ ๊ณผ์ ์ ํตํด ํ์ธต ๋ ์ฑ์ฅํ์ฌ ์์ผ๋ก์ ํ๋ก์ ํธ์์ ๋ ๋์ ๊ฒฐ๊ณผ๋ฌผ์ ๋ง๋ค๊ณ ์ถ์ต๋๋ค.



















