230517.til(next-js-05)

Universe·2023년 5월 18일
0
post-custom-banner

회원 인증기능

가장 최근 프로젝트에서 회원가입 기능의 프론트엔드 담당을 맡아서 했다.
Next 에서는 내가 직접 서버를 만들어 볼 수 있기 때문에 조금 더 기대되는 기능.

원리

회원 인증 기능을 쉽게 설명하면
”이러한 행동을 하기 위해서는 이러한 권한이 필요합니다”
라는 느낌이다.
여기서 “이러한 권한” 이라는 것을 증명하는 방법에는 다양한 종류가 있는데,
대표적으로는 Cookie & Session, JWT token, 같은 것들이 있다.

Session 방식은 유저가 로그인을 시도하면 데이터 베이스에 로그인 정보를 저장해두고
클라이언트에 세션 id를 발급하는 방식이다.
매 요청마다 엄격한 권한 체크를 할 수 있지만 서버의 부담이 증가하는 단점이 있다.

JWT 토큰 방식은 데이터 베이스에 로그인 정보를 저장하지 않고
클라이언트에 암호화된 로그인 정보를 토큰 형식으로 발급한다.
서버에 따로 저장되는 데이터가 없으므로 서버의 부담은 줄어들지만,
토큰 탈취시 대처가 까다롭다는 단점이 있다.

Next js 에서는..

리액트로 한땀한땀 구현하던 회원가입, 인증기능은
넥스트에서 NextAuth.js 라는 훌륭한 라이브러리로 아주 쉽고 간단하게 할 수 있다고 한다.
NextAuth 를 이용해 Github 소셜 로그인을 구현해보자.

구현

Github 의 Setting 탭에 Developer settings 에 들어가서
OAuth Apps 의 key를 발급받는다.
카카오 Developer 에서 key 발급 받는 것과 비슷한 과정.

npm i next-auth

그리고 가장 먼저 해야할 일은 nextauth 의 디렉토리를 설정하는 일이다.

// pages/api/auth/[...nextauth].js

import NextAuth from "next-auth/next";
import GithubProvider from "next-auth/providers/github";

export const authOptions = {
  providers: [
    GithubProvider({
      clientId: process.env.GITHUB_ID,
      clientSecret: process.env.GITHUB_SECRET,
    }),
  ],
  secret: "1234qwer",
};

export default NextAuth(authOptions);

github provider 를 추가해준다.
provider 는 공식문서에서 인증 공급자 정도로 소개하고 있다.

깃허브의 설정 페이지에서 id와 secret을 발급받고 provider에 할당해준다.
저런 비밀스러운 key 는 env 로 처리하는게 좋다.
next.js 에서는 REACT_APP 어쩌고 하는 키워드를 쓰지 않아도 알아서 처리해준다.

그리고 클라이언트 컴포넌트로

"use client";

import { signIn, signOut } from "next-auth/react";

export default function LoginBtn({ session }) {
  return !session ? (
    <button onClick={() => signIn()}>Login</button>
  ) : (
    <button onClick={() => signOut()}>Logout</button>
  );
}

signIn 함수를 import 해서 사용한다.
카카오 소셜 로그인을 구현할 때 리다이렉트 링크를 주던 것과 비슷한 역할.
signOut 으로 자동 로그아웃 기능도 제공하고 있다.

import Image from "next/image";
import LoginBtn from "@/components/LoginBtn";
import { authOptions } from "@/pages/api/auth/[...nextauth]";
import { getServerSession } from "next-auth";
export default async function Home() {
  const session = await getServerSession(authOptions);
  const { name, email, image } = session?.user || {};

  return (
    <>
      <LoginBtn session={session} />
      {session && (
        <>
          <h3>{name}</h3>
          <p>{email}</p>
          <Image src={image} width={200} height={200} alt="profile-image" />
        </>
      )}
    </>
  );
}

서버 컴포넌트에서 getServerSession 함수를 이용하면
로그인 상태인지 아닌지, 로그인이 되었다면 해당 프로바이더에서 제공하는 유저정보를
가져올 수 있다.
위의 로직은 세션이 존재하면 name, email, image 를 제공받아
바인딩해서 화면에 보여주는 로직.

제공받은 Image 를 이용하기 위해서는 추가적으로 설정해줘야 하는 옵션이 있는데,

// next.config.js
const nextConfig = {
  images: {
    domains: ["avatars.githubusercontent.com"],
  },
};

next.config.js 파일에 images-domails 에 제공받은 이미지의 도메인을
넣어주어야만 사용할 수 있다.

profile
Always, we are friend 🧡
post-custom-banner

0개의 댓글