POT 프로젝트

개발 log·2022년 1월 15일
0

프로젝트

목록 보기
4/6

LoL(League of Legend) 파티원 모집 플랫폼


📄 서비스 소개

LOL 게임 유저가 포지션별 필터링을 통해 팀원들을 모집할 수 있는 반응형 웹 서비스입니다.


🗓 진행 기간

2021.11.08 ~ 2021.11.19


🧨 기획 의도

최근 롤드컵이나 영상매체 등 기존 점유율 1위를 유지하며 상승세를 달리는 게임
"LOL(League of Legend)"을 대상으로 5인 팀 게임 특성상 이상적인 포지션으로
플레이하기 힘든 문제를 해결하고자 POT 프로젝트 기획하였습니다.


📋 서비스 아키텍쳐

  1. 로그인을 하기 전 사용자는 게시글 접근만 가능합니다.
  2. 게시글 생성, 작성한 글 확인, 참여자 관리는 유효한 유저만 접근 가능합니다.
  3. 백엔드 측에서 데이터 관리는 fs모듈을 사용하여 DB를 구현했습니다.
  4. Authorization은 JWT, Bcrypt, JOI를 사용했습니다.
  5. 게시글에 접근하기 위한 라우터는 express 라우팅을 사용했습니다.

🎇 핵심 기능

1. 로그인

2. 메인페이지

현재 등록 된 게시글들을 모두 볼 수 있는 페이지로서 통신량을 관리하기 위해
Intersection Observer API를 사용하여 Lazy Loading 기법을 구현했습니다.

3. 글 작성

Quill 에디터 라이브러리를 사용하여 글 작성 기능을 구현했습니다.

4. 신청자 관리

작성자의 글에 현재 신청된 신청자를 모두 볼 수 있으며 포지션별, 티어별 등 필터링 기능을 제공하여 사용자 경험을 높이기 위해 노력했습니다.

5. 참여 승인 시 메일 전송

Node Mailer라이브러리를 사용하여 특정 포지션에 참여시킬 신청자를 참여 승인 할 경우 신청자에게 참여되었다는 메일을 보내고 해당 포지션의 남은 신청자들은 신청 거부 처리하도록 구현했습니다.

6. 신청 후 신청한 게시글 보기

현재 신청한 게시글, 작성한 게시글 등을 확인할 수 있도록 하였습니다.



🎯 수행한 역할

1. 공통으로 사용되는 헤더 제작

JWT토큰이 유효한 지 확인하는 /api/validate 쿼리로 접근하여 미들웨어를 거친 후 사용자의 정보를 렌더링하는 공통 헤더 제작

2. 필터링 조건에 맞춰 신청자 리스트 렌더링

백엔드를 직접 구성했기 때문에 필터링 조건에 맞는 API를 직접 제작하여 조건에 맞는 신청자 리스트 렌더링 기능 구현

  • 백엔드에 대한 지식이 전무했지만 이 경험을 통해 백엔드에서 어떤식으로 API를 제공하는지 알게 됨

3. 신청 승인 시 메일 전송

NodeMailer라이브러리를 사용하여 참여 승인된 신청자에게 메일 전송



❗ 역할 진행 시 생긴 기술적인 문제점

1. 여러 페이지에서 공통으로 사용되는 일종의 컴포넌트 구현

React, Vue와 같은 라이브러리를 사용하지 않고 Vanilla JS로만 구현하는 것이 목표였기에 어떻게 컴포넌트형식으로 헤더를 제작하여 팀원들이 사용하기 편한 헤더를 만들지 고민이었습니다.

2. 메일 전송이 실패했음에도 에러를 표시하지 않는 문제점

NodeMailer라이브러리로 메일 전송기능을 구현했는데 이 때 메일 전송이 실패했음에도 에러를 발생시키지 않아 난항을 겪었습니다.

  • 이때 에러 핸들링의 중요성을 깨달았습니다.

3. 쿠키에 정보를 담았을 때 위험성

이번 프로젝트를 진행하며 쿠키에 정보를 저장하면, 즉 클라이언트 측에 정보를 저장하는 것이 얼마나 위험한 것인지 알게 되었습니다.

  • 단적인 예로 소환사명을 쿠키에 담아 전송하니 사용자가 소환사명을 변경했을 때 서버측 데이터도 변질되는 상황이 생겼습니다.


👍 문제 해결 방안

1. Web Component 적용


class Header extends HTMLElement {
  constructor() {
    super();
    this.attachShadow({ mode: 'open' });
    this._rendered = false;
  }

  connectedCallback() {
    if (this._rendered) return;
    
    this._rendered = true;
    this._setHeader();
    this.render();
  }
  
  async _setHeader() {}
  _renderLoginInfo(summoner) {}
  _guideLogin() {}

  render() {
    this.shadowRoot.innerHTML = `
      <style> ... </style>

      <header>
        <div class="wrapper">
          <h1>
            <a class="logo-link" href="/">
              <img class="logo" src="/images/logo.png" alt="logo">
            </a>
          </h1>
          <nav>
            <a class="nav-link" href="/createdpot"><span class="create-pot">POT 생성</span></a>
            <span class="nav-link login-info"></span>
          </nav>
        </div>
      </header>
    `;
  }
}

customElements.define('login-header', Header);

React의 클래스 컴포넌트처럼 사용가능한 Web Component를 접목시켜
<login-header></login-header>의 형태, 즉 태그 형태로 사용가능하게 하여 재사용성을 높이고 헤더 자체의 안정성을 확보할 수 있었습니다.

2. SMTP 프로토콜을 쉽게 설정할 수 있는 네이버 메일로 전환

기존에는 G-Mail을 사용하여 메일을 전송하려 했으나 원인을 찾던 중 G-Mail의 SMTP 프로토콜을 제대로 설정해주지 않았기 때문이라는 것을 알게되어 설정이 까다로운 G-Mail보다 설정이 간단한 네이버 메일을 사용하여 문제를 해결했습니다.

  • 본질적인 부분을 해결하지 못한 것이기 때문에 많은 아쉬움이 있는 부분입니다.
  • 추후 SMTP 프로토콜을 따로 공부해서 정리하고 G-Mail로 다시 도전해보고자 합니다.

3. 모든 정보를 JWT으로 관리

결국 본질적인 문제점은 클라이언트 측에 저장되어 변경가능성이 있는 쿠키에 정보를 저장했다는 것이었기에 클라이언트측에서 사용하는 사용자 정보를 JWT에 담아 미들웨어를 통해 검증하고 유효한 사용자 정보만을 넘겨받아 렌더링하는 방식으로 변경하였습니다.

  • 미들웨어와 JWT를 사용하여 인증을 조금 더 꼼꼼히 하니 클라이언트 측에서 하는 일이 명료해졌습니다.


✔ 아쉬운 점

1. 공통 헤더 제작 부분

현재는 웹 컴포넌트를 적용하여 해결했지만 제작 당시에는 웹 컴포넌트를 알지 못해 수동으로 관리하는, 즉 재사용성이 낮은 HTML형식으로 사용했었습니다.
HTML을 Copy & Paste방식으로 사용하니 예상치 못한 에러가 자주 발생했었고 디버깅도 어려웠었습니다.

2. G-Mail을 포기하고 네이버 메일로 전환한 점

최초에 G-Mail을 선택한 이유가 보안이 철저하다는 장점 때문이었는데 오히려 너무 철저하고 복잡했던 과정으로 인해 제가 포기했던 상황이 너무 아쉬웠습니다.
추후 메일을 관리해야 되는 상황이 생긴다면 꼭 G-Mail에 대해 공부해서 제대로 적용해보고 싶습니다.

🍳 아쉬운 점 개선방향

1. 웹 컴포넌트 기술 적용

공통 헤더를 함수처럼 사용하기 위해 재사용성이 높은 웹 컴포넌트 기술을 적용하여 유지보수의 편의성을 높였습니다.



👍 프로젝트를 통해 알게 된 점

1. 리팩토링을 병행하며 진행할 때의 장점

POT 프로젝트 이전에는 기능구현에만 집중하고 리팩토링을 한번에 몰아서 하는 방식으로 진행했는데 코드량이 많아질 경우 리팩토링 과정에서 발생하는 연계적인 문제들을 디버깅하기 힘들었고 작성한지 오래 된 코드를 보면 해석하는 것에 시간을 더 쏟아야하는 경우가 있었는데,

이번 프로젝트에서는 팀원들과 하루마다 코드리뷰를 진행하며 리팩토링을 병행하는 형식으로 진행하니, 최종적으로 리팩토링 단계에서 수정할 부분이 줄어들었고 코드의 가독성을 챙기며 프로젝트를 진행할 수 있어서 더 좋았습니다.

2. JWT (JSON Web Token)의 장점

쿠키와 세션은 각각 클라이언트와 서버에 저장한다는 점에서 장단점이 존재했는데,
JWT토큰은 쿠키의 단점인 보안부분과, 세션의 단점인 서버가 여러 개일 경우 새로운 인증을 해야하는 점을 잘 개선한 기술임을 알게 되었습니다.

3. 에러처리의 중요성

NodeMailer를 사용하며 에러를 명확하게 발생시키지 않는다는 점 때문에 큰 난항을 겪었습니다.
덕분에 라이브러리를 만들거나 프로그래밍을 할 때 특히 인터프리터 언어에서 에러처리가 얼마나 중요한지 알게 되었습니다.

profile
개발자 지망생

0개의 댓글