TripMingle [NextJs14, Typescript, vanilla-extract] : Next Route Handler, Next서버에서 데이터 요청하기,

2024. 10. 2. 14:13·프로젝트/여행 동행 웹앱 프로젝트

설명

원래는 Next클라이언트 -> tripmingle 서버로 데이터를 요청했었는데,
이번에 Next서버 -> tripmingle 서버 방식으로 바꾸게 되었다.

 

🔍 왜?

 

트립밍글 프론트를 배포하면서 발생한 브라우저 오류 때문.
처음에는 CORS오류 인가 했는데, CORS와는 다른 MixedContent(혼합된 콘텐츠 정책)오류 였다.

 

Mixed Content: The page at 'https://example.com/index.html' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://example2.com/endpoint'. This request has been blocked; the content must be served over HTTPS.

 

해결할 방법은 백엔드 api 주소를 Https를 붙이던가 아니면,
클라이언트 말고 프론트의 서버에서 데이터 요청을 붙이는 방법이 있다.

그래서 이번에 프론트 서버에서 데이터 요청보내는 방식으로 이 문제를 해결하려한다.

 

Next클라이언트 -> 서버 데이터 요청 을  Next클라이언트 -> Next서버로 데이터 요청하는 걸로 변경

  • Next 클라이언트 
    • 사용자가 직접 상호작용하는 웹 페이지
    • React 컴포넌트들이 여기서 렌더링되고 동작한다.
  • Next 서버
    • NextJs 프레임워크가 운영하는 서버
    • 서버 사이드 렌더링, API라우트 처리 등을 담당한다.
  • 서버
    • Tripmingle의 외부 웹 서버 = 메인 백엔드 

 

(기존) 클라이언트 -> 서버 요청 코드

기존 클라이언트에서 프로젝트 내 로그아웃 하는 함수

// src/api/user.ts

export const kakaoLogout = async () => {
  try {
    const token = getToken();
    const res = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/auth/logout`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        Authorization: `Bearer ${token}`,
      },
    });

    if (!res.ok) throw new Error('로그아웃 실패');
    return res.ok;
  } catch (error) {
    console.error(error);
  }
};

 

route handler 사용해서 바꾼 함수 

 

먼저 클라이언트의 요청은 이렇게 바뀐다.

// src/api/user.ts

export const kakaoLogout = async () => {
  try {
    const res = await fetch(`/api/user/logout`, {
      method: 'POST',
    });

    if (!res.ok) throw new Error('로그아웃 실패');
    return res.ok;
  } catch (error) {
    console.error(error);
  }
};

 

이전과 달리 fetch 주소가 NEXT_PUBLIC_API_URL이 아니라 /api/user/logout인 것을 확인할 수 있다.

해당 url로 요청을 보내면 프로젝트 내 src/app/api/user/logout/route.ts로 요청이 간다.

 

// src/app/api/user/logout/route.ts
import { getAccessToken } from '@/utils/server/token';
import { NextRequest, NextResponse } from 'next/server';

export const POST = async (req: NextRequest) => {
  const baseurl = `${process.env.API_URL}`;
  const pathname = `/auth/logout`;
  let token = await getAccessToken();

  if (!token)
    return NextResponse.json(
      { error: 'access token이 없거나 만료되었습니다.' },
      { status: 500 },
    );

  return await fetch(`${baseurl}${pathname}`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization: `Bearer ${token}`,
    },
    // @ts-ignore -- 연결이 단방향임을 나타냄
    duplex: 'half',
  });
};

 

클라이언트에서 fetch 할때 method가 'POST'라면,

해당 url의 route.ts파일의 POST함수를 실행시킨다.

 

이 방식을 Route handler라고 한다.

 

장점

  • 클라이언트에서 access token에 접근할 수 없어 보안상 장점을 가짐
    • 기존에는 cookie 받으면 jscookie에 저장하는 방식을 사용했는데, 그렇게 되면 브라우저의 application/cookies에서 값이 노출됐다.
    • 현재는 프론트 서버에서 실제 서버로 요청을 보내기 때문에 next server cookie에 access token을 저장하고 사용하고 있다. server cookie의 경우 클라이언트 사이드에서 접근이 안되어 보안면에서 더 낫다고 볼 수 있다.
  • 서버에서 CORS를 신경 쓰지 않아도 된다.
    • CORS는 웹 브라우저의 보안 메커니즘인데, 서버 간 통신은 브라우저가 관여하지 않기 때문
  • 데이터 요청이 개발자 도구의 network에 노출되지 않는다.
    • 개발자 도구의 network는 클라이언트측의 네트워크 활동만을 보여주기 때문에, network탭에 보이지 않는다.

 

고민

그러나, 이 방식을 구현하면서 들은 생각이 있다.

이게 그냥 server단에서 fetch함수 불러서 호출하는 거에 비해 장점이 뭐가 있을까?

 

refresh 토큰으로 access 토큰을 발급하려할 때, 해당 기능은 굳이 서버 api 페이지를 새로 만들 필요없이

utils에 넣는 게 낫다고 판단했다.

 

그런데 이런 방식이 된다면 굳이 data 받아오거나 post하는 함수를 route handler 방식으로 할 필요가 있을까 ?

어떻게 보면, 프론트 -> 프론트 서버, 프론트 서버 -> 서버 이렇게 두 단계를 거쳐야 하는데,

그냥 함수 호출로 데이터 fetching하는 것보다 더 번거롭다. 

 

좀 더 찾아보고 더 효율적인 방법으로 사용해보아야 겠다.

 

------- 10/30 수정

알아보니, use server로 서버단에서 데이터 패칭을 요청하는 것이나, route handler 방법을 통해 데이터 요청하는 것이나

두 방법 모두 어차피 프론트에서 프론트 서버를 호출하는 것이기 때문에, 큰 차이는 없는 것 같다!

 

 

'프로젝트 > 여행 동행 웹앱 프로젝트' 카테고리의 다른 글

TripMingle [NextJs14, Typescript, vanilla-extract] : Skeleton UI 적용하기  (1) 2024.10.31
TripMingle [NextJs14, Typescript, vanilla-extract] : NextJs14, nginx, pm2, Amazon Linux EC2, Github CI/CD, 무중단 배포, BlueGreen배포  (1) 2024.10.30
TripMingle [NextJs14, Typescript, vanilla-extract] : NextJs14 배포하기, EC2, Amazon Linux, pm2, nginx, 가비아 + Route 53 이용해서 도메인 등록하기  (4) 2024.09.23
TripMingle [NextJs14, Typescript, vanilla-extract] : react-calendar 커스텀하기, react-calendar 기간 선택  (0) 2024.07.25
TripMingle [NextJs14, Typescript, vanilla-extract] : 페이지네이션, 페이지 컴포넌트 개발  (0) 2024.07.17
'프로젝트/여행 동행 웹앱 프로젝트' 카테고리의 다른 글
  • TripMingle [NextJs14, Typescript, vanilla-extract] : Skeleton UI 적용하기
  • TripMingle [NextJs14, Typescript, vanilla-extract] : NextJs14, nginx, pm2, Amazon Linux EC2, Github CI/CD, 무중단 배포, BlueGreen배포
  • TripMingle [NextJs14, Typescript, vanilla-extract] : NextJs14 배포하기, EC2, Amazon Linux, pm2, nginx, 가비아 + Route 53 이용해서 도메인 등록하기
  • TripMingle [NextJs14, Typescript, vanilla-extract] : react-calendar 커스텀하기, react-calendar 기간 선택
밍끼c
밍끼c
성장하는 웹 프론트엔드 개발자
  • 밍끼c
    밍끼개발일기
    밍끼c
  • 전체
    오늘
    어제
    • 분류 전체보기 (36)
      • 프로젝트 (15)
        • 선행 커뮤니티 웹앱 프로젝트 (5)
        • 여행 동행 웹앱 프로젝트 (9)
        • 투두 웹앱 프로젝트 (1)
      • 삽질 로그 (8)
      • 코딩테스트 (10)
      • 후기 (3)
  • 블로그 메뉴

    • 홈
    • 태그
    • 방명록
  • 링크

  • 공지사항

  • 인기 글

  • 태그

    CI/CD
    inline-flex
    pm2
    DP
    gooleoauth2
    TypeScript
    vanillaextract
    level3
    globalfontface
    tripmingle
    react
    react-oauth
    vanilla-extract
    googlelogin
    zustand
    코딩테스트
    프로그래머스
    GithubActions
    globaltheme
    goodplassu
    Nextjs14
    ParametricSearch
    nginx
    pnpm
    softeer
    JavaScript
    level2
    server side fetching
    route handler
    react-calendar
  • 최근 댓글

  • 최근 글

  • hELLO· Designed By정상우.v4.10.0
밍끼c
TripMingle [NextJs14, Typescript, vanilla-extract] : Next Route Handler, Next서버에서 데이터 요청하기,
상단으로

티스토리툴바