본문 바로가기
Web Study/Next.js

코딩애플 - 마지막 Next.js ... Middleware

by 쿠리의일상 2023. 7. 9.

드디어 완강에 다가왔다 !

마무리도 확실하게 해주자~

Middleware ?

서버에서 하나의 기능을 100만개의 서버 API 기능에 동시에 적용하고 싶은 경우

미들웨어를 사용하면 가능하다.

즉, 요청이랑 응답 사이에 간섭하는 코드를 미들웨어라고 한다.

 

미들웨어 만들기

Next.js 폴더의 루트 영역(App폴더와 같은 위치)에 middleware.js 라는 파일을 만들어준다.

import { NextResponse } from "next/server";

export function middleware(request) {
	// 미들웨어 내용
    
    
    return NextResponse.next() // 서버로 통과
    return NextResponse.redirect() // 다른 페이지로 강제 이동 (주소창이 변경)
    return NextResponse.rewrite() // 다른 페이지로 강제 이동 (주소창은 변경 안됨)
}

next/server 에서 NextResponse 를 import 해오고, 기본적으로 미들웨어는 export default 를 해주지 않고 export 만 해준다.

브라우저에서 GET, POST 요청이 오면
-> middleware.js 안의 코드가 실행되고
-> 그 이후에 각 api url 의 서버 코드가 실행되는 순서

 

미들웨어 안에서 쓸 수 있는 정보는...

  • request.nextUrl : 현재 유저가 요청한 url
  • request.cookies : 유저의 쿠키
  • request.headers : 유저의 headers 정보
    • 이전 방문 페이지
    • 사용중인 OS, 브라우저
    • 선호하는 언어
    • IP
    • 쿠키 등...

 

미들웨어의 가장 마지막에는

  • NextResponse.next() // 서버로 통과
  • NextResponse.redirect() // 다른 페이지로 강제 이동 (주소창이 변경)
  • NextResponse.rewrite() // 다른 페이지로 강제 이동 (주소창은 변경 안됨)

꼭 NextResponse 로 응답을 보내줘야 서버로 넘어간다!

 

미들웨어 활용

import { NextResponse } from "next/server";

export function middleware(request) {
  if(request.nextUrl.pathname.startsWith('/list')) { // /list 를 포함한 하위 주소에 있으면
    console.log(request.headers.get('sec-ch-ua-platform')); // OS 정보 출력
    return NextResponse.next();
  }
}

 

  const session = await getToken({ req : request }) // JWT 형태로 로그인 처리해줬을 때
  if (request.nextUrl.pathname.startsWith('/write')) {
    if (session === null) {
      return NextResponse.redirect(new URL('/api/auth/signin', request.url));
    }
  }

로그인이 안되어있으면 로그인 페이지로 보내주는 미들웨어

 

request.cookies.get('쿠키이름')  //출력
request.cookies.has('쿠키이름')  //존재확인
request.cookies.delete('쿠키이름')  //삭제

미들웨어 안에서 쿠키를 위처럼 다뤄줄 수 있고

const response = NextResponse.next()
  response.cookies.set({
    name: 'mode',
    value: 'dark',
    maxAge: 3600,
    httpOnly : true
  })  
return response  //쿠키생성

NextResponse.next() 에 cookies 를 set() 하여 쿠키를 생성해서 보내줄 수도 있다.

name 이 key 가 되고 value 에 값을 넣어주는 것, maxAge 는 유효기간이다.

위에 httpOnly : true 로 지정해두면 유저가 자바스크립트로 쿠키를 조작할 수 없게 만들 수 있다. 물론 개발자도구에서 직접 수정하는 것은 막을 수 없으므로 쿠키는 조작하면 큰일나는 정보를 담아주지 말고 서버에 보관해준다.

*** 쿠키는 프론트에서도, 서버에서도 다룰 수 있는 것임.

브라우저에 있는 건 유저가 언제든 조작이 가능하다는 것을 잊으면 안된다.

내 프로젝트의 경우 middleware.js 를 못 읽어오는 이슈가 있어서 실습해보진 못했다. 버전이 강의랑 똑같은데 왜 안되는지 찾다가 도저히 안되서 그냥 넘어감 ㅜ

 

Server actions 

강의 당시 실험적 기능이라고 한다. (Next.js 13.4 버전 이후부터 가능)

보통 DB에 데이터를 저장, 수정 등을 하고 싶으면 당연히 서버를 거쳐야 한다.

만약 이 과정이 번거롭거나 귀찮으면 page.js 에서 처리해줄 수 있는 방법이 바로 Server action 이다.

 

next.config.js 파일을 열어서 아래의 설정을 추가해준다.

module.exports = {
  experimental: {
    serverActions: true,
  },
};

 

Server actions 은 서버 컴포넌트 안에서 요청된 form 내용을 파라미터에 바로 받아와서 사용해줄 수 있다.

export default async function Write() {

  // 서버기능
  async function handleSubmit(formData) {
    'use server';
    console.log(formData)
    console.log(formData.get('title'))
  }
 
 
  // 폼
  return (
    <form action={handleSubmit}> 
      <input type="text" name="title" />
      <button type="submit">Submit</button>
    </form>
  );
}
  1. form 의 action 에 서버용으로 사용할 함수를 넣어준다.
  2. 해당 함수 안에 'use server'; 를 적어주고, 파라미터로 formData 를 받아준다.
  3. use server 를 작성하면 함수 내용을 자동으로 서버 API 로 만들어주고, 함수 안에 있는 코드는 유저에게 노출되는 코드가 아니라 서버코드이므로 폼 내용을 DB에 저장하거나 검사할 수 있다.

 

추가로 form 태그 말고 form 태그 안에 있는 input 태그 안에 formAction 에다가 서버 액션 함수를 넣어줘도 된다.
<button formAction={함수}>버튼</button>

 

기본적으로 action 은 폼 전송 시 새로고침이 되지 않는다

새로 고침 처리를 해주려면 useRouter 의 router.refresh() 를 써주거나

 

import { revalidatePath } from "next/cache"

revalidatePath('/URL') 를 사용하면 해당 url 에 있던 캐시를 삭제하고 다시 생성하면서 다른 부분만 바꿔주는 최적화 새로고침처리도 된다. SSR 에서 서버 컴포넌트로 SPA처럼 업데이트를 해주고 싶을 때 잘 사용된다.

 

끗!