Skip to content
ย 
ย 

Repository files navigation

๋‚˜ํ˜ผ์ž ๋จน๋Š”๋‹ค

eating_alone_mainlogo9

๐Ÿ“ฑํ”„๋กœ์ ํŠธ ์†Œ๊ฐœ

๋„ค์ด๋ฒ„ ํด๋ผ์šฐ๋“œ ๋ฐ๋ธŒ์˜ต์Šค 3๊ธฐ 4์กฐ - ์„ธ๋ฏธ ํ”„๋กœ์ ํŠธ
๊ฐœ๋ฐœ๊ธฐ๊ฐ„: 2023.12.04 - 2023.12.26

  • <๋‚˜ํ˜ผ์ž ๋จน๋Š”๋‹ค>๋Š” ์ž์ทจ์ƒ๋“ค์ด ์„œ๋กœ ๋ ˆ์‹œํ”ผ๋ฅผ ์ œ๊ณตํ•˜๊ณ  ๊ณต์œ ํ•˜๊ณ , ์ค‘๊ณ  ๊ฑฐ๋ž˜ ๊ด€๋ จ ์ปค๋ฎค๋‹ˆํ‹ฐ ํ™œ๋™์„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œ์ž‘ํ•œ ์ปค๋ฎค๋‹ˆํ‹ฐ ๊ธฐ๋ฐ˜ ํ”„๋กœ์ ํŠธ์ž…๋‹ˆ๋‹ค. ๋ฐ๋ธŒ์˜ต์Šค ์ˆ˜์—…์—์„œ ํ•™์Šตํ•œ Maven Project๋ฅผ ๋ณต์Šตํ•˜๋ฉฐ ํ™œ์šฉํ•˜์˜€์Šต๋‹ˆ๋‹ค.

๋ฐœํ‘œ ์ž๋ฃŒ

๋ฐœํ‘œ ์ž๋ฃŒ PPT


๐Ÿ‘คํŒ€์› ์†Œ๊ฐœ

contributors

๐Ÿ—๏ธ์•„ํ‚คํ…์ณ

Infra Architecture

๐Ÿ’ฝERD

erd

โš™๏ธ๊ธฐ์ˆ  ์Šคํƒ

Environment

Front-End

Back-End

Java MyBatis

Server & Publish

Database

Communication


๐Ÿ“ŠํŽ˜์ด์ง€ ๊ตฌ์„ฑ

ํ™ˆ ํ™”๋ฉด
ํ™ˆ ํ™”๋ฉด
๋ ˆ์‹œํ”ผ ํ™”๋ฉด
๊ทธ๋ฆฌ๋“œ1
๊ทธ๋ฆฌ๋“œ2
๊ฒ€์ƒ‰
๊ธ€ ์ž‘์„ฑ
๊ธ€ ์ˆ˜์ •/์‚ญ์ œ
์ƒ์„ธ ํŽ˜์ด์ง€
์ปค๋ฎค๋‹ˆํ‹ฐ ํ™”๋ฉด
์ปค๋ฎค๋‹ˆํ‹ฐ ํ™”๋ฉด
๊ธ€ ์ž‘์„ฑ
๊ธ€ ์ˆ˜์ •/์‚ญ์ œ
์ƒ์„ธ ํŽ˜์ด์ง€
๋ฒผ๋ฃฉ์‹œ์žฅ ํ™”๋ฉด
๋ฒผ๋ฃฉ์‹œ์žฅ ํ™”๋ฉด
๊ธ€ ์ž‘์„ฑ
์ƒ์„ธ ํŽ˜์ด์ง€

โœ”๏ธ๋‹ด๋‹น ์„œ๋ธŒ ์‹œ์Šคํ…œ ๊ตฌํ˜„ ๊ธฐ๋Šฅ

1. ๋ฉ”์ธํ™”๋ฉด ๊ตฌ์„ฑ

์ž๋™ Swiper ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ ˆ์‹œํ”ผ, ์ปค๋ฎค๋‹ˆํ‹ฐ, ๋ฒผ๋ฃฉ์‹œ์žฅ์„ ์ด๋ฏธ์ง€๋กœ ์†Œ๊ฐœ. ํด๋ฆญ ์‹œ ํ•ด๋‹น ๋งํฌ ์ด๋™.

๋ฉ”์ธํ™”๋ฉด

2. ํšŒ์›๊ฐ€์ž… ๊ธฐ๋Šฅ

ํšŒ์›๊ฐ€์ž… ์‹œ ์ด๋ฉ”์ผ ์ค‘๋ณต ์ฒดํฌ, ๋‹‰๋„ค์ž„ ์ค‘๋ณต ์ฒดํฌ ๊ธฐ๋Šฅ์„ ํ•˜๋Š” 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","์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ ๋‹‰๋„ค์ž„ ์ž…๋‹ˆ๋‹ค.");
        }
ํšŒ์›๊ฐ€์ž…

3. ๋กœ๊ทธ์ธ/๋กœ๊ทธ์•„์›ƒ ๊ธฐ๋Šฅ

์„ธ์…˜ ์ฟ ํ‚ค์— ๋Œ€ํ•œ ์ดํ•ด๋ฅผ ํ†ตํ•ด ๋กœ๊ทธ์ธ์„ ํ•ด์•ผ ์ปค๋ฎค๋‹ˆํ‹ฐ ๋“ฑ๋ก๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ตฌํ˜„.

๋กœ๊ทธ์ธ/๋กœ๊ทธ์•„์›ƒ ๊ธฐ๋Šฅ

4. Custom Annotation + Custom Exception์„ ์‚ฌ์šฉํ•œ ๋กœ๊ทธ์ธ ๋ฆฌํ„ด

@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;
        }
    }
}
  1. @ControllerAdvice์™€ @ExceptionHandler ๋ถ€๋ถ„ ์ด ๋ถ€๋ถ„์€ ์ด์ „ ์„ค๋ช…๊ณผ ๋™์ผํ•˜๊ฒŒ ์ „์—ญ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๊ธฐ๋ฅผ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. @ExceptionHandler(semi.customException.NotLoggedInException.class)์€ ๋กœ๊ทธ์ธ๋˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ๋ฐœ์ƒํ•˜๋Š” NotLoggedInException์„ ์ฒ˜๋ฆฌํ•˜๋Š” ์—ญํ• ์„ ํ•˜๋ฉฐ, ๋กœ๊ทธ์ธ ํŽ˜์ด์ง€๋กœ ๋ฆฌ๋‹ค์ด๋ ‰ํŠธํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์˜ˆ์™ธ๋ฅผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ์™ธ ๋ฐœ์ƒ ์‹œ, ์‚ฌ์šฉ์ž๊ฐ€ ๋ฐฉ๋ฌธํ•˜๋ ค๋˜ ํŽ˜์ด์ง€์˜ URL์„ ์„ธ์…˜์— ์ €์žฅํ•˜๊ณ , ๋‚˜์ค‘์— ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธํ•œ ํ›„ ์›๋ž˜ ๊ฐ€๋ ค๋˜ ํŽ˜์ด์ง€๋กœ ๋‹ค์‹œ ์ด๋™์‹œํ‚ค๋Š” ๋กœ์ง์ž…๋‹ˆ๋‹ค.

  2. getRequestUri() ๋ฉ”์„œ๋“œ ๋ถ„์„ ์ด ๋ฉ”์„œ๋“œ๋Š” ํ˜„์žฌ ์š”์ฒญ๋œ URI๋ฅผ ๊ฐ€์ ธ์˜ค๋Š” ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์‚ฌ์šฉ์ž๊ฐ€ ๋กœ๊ทธ์ธํ•˜์ง€ ์•Š์€ ์ƒํƒœ์—์„œ ์–ด๋–ค ํŽ˜์ด์ง€์— ์ ‘๊ทผํ–ˆ๋Š”์ง€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

    1. RequestAttributes requestAttributes = RequestContextHolder.currentRequestAttributes(); Spring์˜ RequestContextHolder๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ํ˜„์žฌ ์š”์ฒญ๊ณผ ๊ด€๋ จ๋œ ์†์„ฑ์„ ๊ฐ€์ ธ์˜ต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํ˜„์žฌ HTTP ์š”์ฒญ ๊ฐ์ฒด์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
    1. HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest(); ServletRequestAttributes ๊ฐ์ฒด๋กœ ์บ์ŠคํŒ…ํ•œ ํ›„, HttpServletRequest ๊ฐ์ฒด๋ฅผ ์–ป์Šต๋‹ˆ๋‹ค. ์ด ๊ฐ์ฒด๋Š” ํ˜„์žฌ HTTP ์š”์ฒญ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๋‹ด๊ณ  ์žˆ์œผ๋ฉฐ, ์ด๋ฅผ ํ†ตํ•ด URI๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    1. String requestUri = request.getRequestURI(); getRequestURI()๋Š” ํ˜„์žฌ ์š”์ฒญ๋œ URI ๊ฒฝ๋กœ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, /member/profile ๊ฐ™์€ URL ๊ฒฝ๋กœ๋ฅผ ์–ป์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
    1. String contextPath = request.getContextPath(); getContextPath()๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ปจํ…์ŠคํŠธ ๊ฒฝ๋กœ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด /app์ด๋ผ๋Š” ๊ฒฝ๋กœ์—์„œ ์‹คํ–‰ ์ค‘์ด๋ฉด /app์ด ์ปจํ…์ŠคํŠธ ๊ฒฝ๋กœ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค.
    1. 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);
    }
}
  1. supportsParameter(MethodParameter methodParameter)
  • ์—ญํ• : ์ด ๋ฉ”์„œ๋“œ๋Š” ์ฃผ์–ด์ง„ ๋ฉ”์„œ๋“œ ํŒŒ๋ผ๋ฏธํ„ฐ๊ฐ€ ์ฒ˜๋ฆฌ ๊ฐ€๋Šฅํ•œ ํŒŒ๋ผ๋ฏธํ„ฐ์ธ์ง€๋ฅผ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค.
  • hasLoginAnnotation: ํŒŒ๋ผ๋ฏธํ„ฐ์— @Login ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์–ด ์žˆ๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ด ์–ด๋…ธํ…Œ์ด์…˜์ด ๋ถ™์€ ํŒŒ๋ผ๋ฏธํ„ฐ๋งŒ ์ด resolver๊ฐ€ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
  • hasMemberType: ํŒŒ๋ผ๋ฏธํ„ฐ ํƒ€์ž…์ด MemberDto ํด๋ž˜์Šค ๋˜๋Š” ๊ทธ ํ•˜์œ„ ํด๋ž˜์Šค์ธ์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, MemberDto ํƒ€์ž…์˜ ๊ฐ์ฒด๋งŒ ์ฒ˜๋ฆฌ ๋Œ€์ƒ์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.
  • ๊ฒฐ๊ณผ: ๋‘ ์กฐ๊ฑด์ด ๋ชจ๋‘ ์ฐธ์ด๋ฉด true๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ ํ•ด๋‹น ํŒŒ๋ผ๋ฏธํ„ฐ๋ฅผ ์ฒ˜๋ฆฌํ•  ์ˆ˜ ์žˆ์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.
  1. 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 ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•˜์—ฌ, ๋ฉ”์„œ๋“œ ํŒŒ๋ผ๋ฏธํ„ฐ๋กœ ์ž๋™์œผ๋กœ ์ „๋‹ฌ๋˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

๋กœ๊ทธ์ธ ํ™”๋ฉด์œผ๋กœ ๋ฆฌํ„ด

๐Ÿ”ง์•„์‰ฌ์šด ์  ๋ฐ ์ถ”๊ฐ€ํ•˜๊ณ  ์‹ถ์€ ๊ธฐ๋Šฅย 

1. ์ž…๋ ฅ์ฐฝ์—์„œ ๋ฐ”๋กœ ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ

  • ์„ ์ • ์ด์œ 
    • ์‚ฌ์šฉ์ž ์ž…์žฅ์—์„œ ์ •๋ณด๋ฅผ ์ž…๋ ฅํ•˜๊ณ  ์ˆ˜์ •ํ•˜๋Š” ๊ฒƒ๋ณด๋‹ค ๋ฐ”๋กœ ๊ฒฐ๊ณผ๋ฅผ ๋ณด์—ฌ์คŒ์œผ๋กœ ์‚ฌ์šฉ์ž ํŽธ์˜์„ฑ๊ณผ ์ •ํ™•ํ•œ ๋ฐ์ดํ„ฐ๋ฅผ ์ˆ˜์ง‘ํ•˜๊ธฐ ์œ„ํ•ด์„œ ๊ฐœ์„ ํ•ด์•ผ ํ•  ๋ถ€๋ถ„์ด๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.
  • ๊ฐœ์„  ๋ฐฉํ–ฅ
    • ์œ ํšจ์„ฑ ๊ฒ€์‚ฌ๊ฐ€ ๋ชจ๋‘ ํ†ต๊ณผ๋œ ๊ฒฝ์šฐ ๋‹ค์Œ ๋ฒ„ํŠผ์ด ํ™œ์„ฑํ™”๋˜๋ฉฐ, ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๋ฉด ํ”„๋กœํ•„ ์„ค์ • ํ™”๋ฉด์ด ๋‚˜ํƒ€๋‚˜๋„๋ก ์ ์šฉํ•ด๋ณด๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.
  • ์ถ”ํ›„ ๊ด€๋ จ ์ง€์‹ ์Šต๋“์„ ์œ„ํ•œ ํ‚ค์›Œ๋“œ
    • html, javascript

2. ๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™” ํ›„ ์ €์žฅ

  • ์„ ์ • ์ด์œ 
    • ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์•”ํ˜ธํ™”๋ฅผ ๊ณ ๋ คํ•˜์ง€ ์•Š๊ณ  DB์— ์ €์žฅํ•˜์—ฌ ๋ฐ์ดํ„ฐ ์œ ์ถœ์˜ ์œ„ํ—˜๊ณผ ์‚ฌ์šฉ์ž์˜ ์‹ ๋ขฐ๋„๊ฐ€ ๋–จ์–ด์ง€๊ฒŒ ๋˜๋Š” ์•„์‰ฌ์›€์ด ๋‚จ์•˜์Šต๋‹ˆ๋‹ค.
  • ๊ฐœ์„  ๋ฐฉํ–ฅ
    • SHA-256, bcrypt, PBKDF2, Argon2 ๋“ฑ๊ณผ ๊ฐ™์€ ์•ˆ์ „ํ•œ ํ•ด์‹œ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ•ด์‹œํ™”ํ•ด ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.
    • ์†”ํŠธ, ํŽ˜ํผ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  ์‚ฌ์šฉํ•˜์—ฌ ๋”์šฑ ์•ˆ์ „ํ•œ ์‚ฌ์šฉ์ž ์ธ์ฆ ์‹œ์Šคํ…œ์„ ๊ตฌ์ถ•ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ถ”ํ›„ ๊ด€๋ จ ์ง€์‹ ์Šต๋“์„ ์œ„ํ•œ ํ‚ค์›Œ๋“œ
    • ํ•ด์‹œ ํ•จ์ˆ˜ ์‚ฌ์šฉ, ์†”ํŠธ, ํŽ˜ํผ

๐Ÿ’ญํ”„๋กœ์ ํŠธ ์†Œ๊ฐ ๋ฐ ์˜์˜

  • ๊ฐœ์ธ Mini ํ”„๋กœ์ ํŠธ๋งŒ ๊ตฌํ˜„ํ•˜๋‹ค๊ฐ€ ์ฒ˜์Œ์œผ๋กœ ํ•ด๋ณธ ํŒ€ ํ”„๋กœ์ ํŠธ์˜€์Šต๋‹ˆ๋‹ค. ์ฐจ๊ทผ์ฐจ๊ทผ ๊ธฐ์ดˆ๋ถ€ํ„ฐ ์Œ“๋Š”๋‹ค๋Š” ๋งˆ์Œ๊ฐ€์ง์œผ๋กœ ์ „๋ฐ˜์ ์ธ ํ™”๋ฉด ๊ตฌ์„ฑ๊ณผ ๋กœ๊ทธ์ธ์„ ๋‹ด๋‹นํ•˜์˜€์Šต๋‹ˆ๋‹ค.

  • ์†Œํ†ต๊ณผ ํ”ผ๋“œ๋ฐฑ์„ ํ†ตํ•ด ํŒ€์›๋“ค๊ณผ ์˜๊ฒฌ์„ ์กฐ์œจํ•˜๋Š” ๊ฒƒ์€ ์„œ๋กœ์˜ ์ง€์‹์„ ๋”์šฑ ๊ฐ€์น˜์žˆ๊ฒŒ ๋งŒ๋“ค์–ด์ฃผ๋Š” ๊ณ„๊ธฐ๊ฐ€ ๋˜์–ด ์ข‹์€ ๊ฒฐ๊ณผ๋ฅผ ์ด๋Œ์–ด๋‚ผ ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค.

  • ๊ตฌํ˜„ ์ค‘ ๋ฐœ์ƒํ•œ ์˜ค๋ฅ˜์™€ ์‹ค์ˆ˜๋ฅผ ๊ธฐ๋กํ•˜๊ณ , ์ด๋ฅผ ํ†ตํ•ด ๋ฌธ์ œ๋ฅผ ๋ณด์™„ํ•˜๋Š” ๊ฒƒ์˜ ์ค‘์š”์„ฑ์„ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ณผ์ •์„ ํ†ตํ•ด ํ•œ์ธต ๋” ์„ฑ์žฅํ•˜์—ฌ ์•ž์œผ๋กœ์˜ ํ”„๋กœ์ ํŠธ์—์„œ ๋” ๋‚˜์€ ๊ฒฐ๊ณผ๋ฌผ์„ ๋งŒ๋“ค๊ณ  ์‹ถ์Šต๋‹ˆ๋‹ค.

About

๐Ÿณ์š”๋ฆฌ ๋ ˆ์‹œํ”ผ ๊ณต์œ  ํ”Œ๋žซํผ ํ”„๋กœ์ ํŠธ

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages