로그인 & 회원가입 기능 구현

양현민·2025년 3월 31일
1

글을 시작하며...
처음에는 단순히 로그인/회원가입 구현은 간단할 것이라고 생각했지만,
막상 직접 만들다 보니 많은 개념들이 얽혀 있었다.

DTO(Data Transfer Object) 라는 새로운 구조
세션/쿠키/토큰이라는 인증 방식의 차이
✅ 간단한 기능 구현

이번 글에서는 내가 직접 구현한 방식과 함께 위 개념들을 차근차근 정리해보려고 한다.
참고자료 : https://youtu.be/RhM1bQ76Tv0?si=CofxaZoG9whyzr5R


1️⃣ DTO란?

✔️ DTO란?
DTO는 Data Transfer Object의 줄임말로,
계층 간 데이터 전달을 위한 객체이다.
즉, Controller → Service → Repository로 데이터가 이동할 때
그 정보를 묶어서 전달한다.

Entity ←→ DTO ←→ View (Controller)


그런데 그냥 Entity로 넘기면 안 되나?

❌ Entity를 직접 View로 넘길 경우 단점

  • 보안 취약: DB 컬럼 중 민감한 정보까지 노출될 수 있음
  • 결합도 상승: View가 Entity에 강하게 의존하게 됨
  • 유연성 부족: View에 맞춰 데이터를 가공하기 어려움

그래서 중간에 DTO를 두는 것이 유지보수보안 면에서 훨씬 좋다.


📌 회원가입 요청 처리 (Controller)

@PostMapping("/member/save")
public String save(@ModelAttribute MemberDTO memberDTO) {
    memberService.save(memberDTO);
    return "redirect:/member/login";
}

여기서 memberDTO는 사용자가 입력한 회원가입 정보를 담고 있는 DTO이다.
이 객체는 MemberService로 전달되어 DB 저장을 위한 Entity로 변환된다.


📌 DTO → Entity 변환 (Service)

MemberEntity memberEntity = MemberEntity.toMemberEntity(memberDTO);
memberRepository.save(memberEntity);

DTO는 DB 저장이 불가능하기 때문에,
먼저 Entity로 변환해서 memberRepository.save()를 호출해야 한다.


📌 Entity → DTO 변환 (로그인 성공 시)

MemberDTO loginResult = MemberDTO.tomemberDTO(memberEntity);

로그인 성공 후, DB에서 조회한 Entity 객체를 다시 DTO로 변환하여 Controller로 넘긴다.


📦 MemberDTO 클래스 내부

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class MemberDTO {
    private Long id;
    private String memberName;
    private String memberEmail;
    private String memberPassword;

    public static MemberDTO tomemberDTO(MemberEntity memberEntity) {
        MemberDTO memberDTO = new MemberDTO();
        memberDTO.setId(memberEntity.getId());
        memberDTO.setMemberName(memberEntity.getMemberName());
        memberDTO.setMemberEmail(memberEntity.getMemberEmail());
        memberDTO.setMemberPassword(memberEntity.getMemberPassword());
        return memberDTO;
    }
}

정리하자면

✔️ Entity는 DB와 연결되는 핵심 모델
✔️ DTO는 데이터 전달을 위한 전용 객체
둘은 역할이 다르기 때문에,
계층 간 역할 분리를 위해 반드시 DTO가 필요하다.


2️⃣ 세션 / 쿠키 / 토큰 차이

로그인 인증에는 대표적으로 세션,쿠키,토큰 방식이 있다.
각 방식은 어디에 정보를 저장하느냐, 그리고 누가 인증 상태를 기억하느냐에 따라 구분된다.


✅ 세션 (Session)

  • 서버가 사용자 정보를 저장
  • 로그인 시 서버가 세션 ID를 생성 → 클라이언트에 전달 (보통 쿠키로)
  • 이후 요청마다 세션 ID를 통해 로그인 상태 유지
  • 상태 유지 방식 (Stateful)
session.setAttribute("loginEmail", loginResult.getMemberEmail());

현재 프로젝트에서는 이 방식 사용
-> 로그인 성공 시 서버에 사용자 정보 저장
-> 페이지 이동해도 로그인 상태 유지

✔️ 장점: 서버가 사용자 상태를 확실히 기억함
❌ 단점: 서버가 모든 사용자 상태를 기억해야 해서 메모리 부담 있음


✅ 쿠키 (Cookie)

  • 클라이언트(브라우저)가 정보 저장
  • 서버가 쿠키 설정 -> 브라우저가 이후 요청마다 자동 전송
  • 자동 로그인, UI 설정 등에 사용
  • 직접 인증 정보를 담지는 않음 (보통 세션 ID 보관용)

✔️ 장점: 간단하고, 자동 설정 가능
❌ 단점: 보안에 취약 (중요한 정보 직접 넣으면 안 됨)


✅ 토큰 (Token, JWT)

  • 클라이언트가 토큰 저장
  • 로그인 시 토큰 발급 -> 이후 요청마다 헤더에 토큰 포함
  • 서버는 토큰만 검사 (사용자 상태 저장 X)
  • 무상태 방식 (Stateless) -> REST API, 모바일 앱에서 주로 사용

✔️ 장점: 서버에 저장할 게 없어서 확장성 좋고 가벼움
❌ 단점: 토큰이 유출되면 위험! → 재발급, 만료처리 등 신경 써야 함


✨ 요약

구분저장 위치특징상태 유지
세션서버서버가 관리상태 유지 (Stateful)
쿠키클라이언트브라우저 저장클라이언트 중심
토큰클라이언트JWT 등으로 암호화Stateless

3️⃣ 간단한 기능 소개

🏠 메인 화면

  • 프로젝트의 시작 페이지

📝 회원가입 기능

  • 이름,이메일,비밀번호를 입력하여 회원가입
  • 입력값을 DTO로 받아 Service -> Repository 흐름으로 처리

🔐 로그인 기능 (세션 기반)

  • 입력한 이메일/비밀번호를 검사하여 로그인
  • 로그인 성공 시 세션에 사용자 정보 저장 -> 페이지 이동 시에도 로그인 유지

✍️ 게시판 글쓰기

  • 로그인한 사용자만 글쓰기 가능
  • 제목, 내용, 이미지 업로드 작성하면 게시물 리스트로 이동


처음에는 단순히 로그인이나 회원가입만 만들면 끝날 줄 알았다.
하지만 직접 하나하나 구현해 나가다 보니
생각보다 많은 개념들이 얽혀 있었고
그걸 하나씩 해결해 나가는 과정이 점점 재미있어졌다.

처음엔 볼품없는... 게시판이었지만
AI의 도움을 받아 UI를 조금씩 다듬고, 기능을 추가하면서
내가 만든 서비스에 애정이 생겨가는 것 같아 뿌듯하다 🤩

2개의 댓글

comment-user-thumbnail
2025년 3월 31일

DTO 구조와 흐름에 대해 이해하기 쉽도록 잘 정리해주셔서 좋았습니다! 😄

답글 달기
comment-user-thumbnail
2025년 4월 1일

DTO에 대해서 정확하게 잘 몰랐는데 그 부분을 정리해주신 부분이 정말 좋고 유익했습니다~~ 수고하셨습니다.

답글 달기