Learn/Next.js

Next.js (7) 로그인 방식 정리 및 OAuth 기능 구현

zeereo 2023. 7. 9. 09:01

 

 

간단한 개념정리

 

** JWT, session, OAuth
1. session 방식 (DB에서 session 아이디 확인)
 - 로그인/아이디/유효기간/세션 id
 - 장점 : 유저의 GET/POST 요청마다 로그인상태 체크가능
 - 단점 : DB가 힘들어 함 -> 보완: redis 세션용 DB (입출력이 빠름)
2. token 방식 (server에서 확인, server에서 위조확인)
 - 장점 : DB까지 가지 않아 유저가 많으면 편함
 - 단점 : 나쁜사람한테 해킹 당하기 쉬움 -> 보완 : 나쁜사람 DB 저장 , 토큰만의 방식 사라짐

 ** OAuth
 1. 사용권한 대여/ 회원정보 대여 ( 소셜 로그인 )


** Next.js에서는 라이브러리 설치하고 코드 복붙하면 쉬움
(nextAuth.js / Auth.js)
Id/비번 시 JWT강제로 사용 (session 금지)

 

실제로 OAuth 구현 해보기

 

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

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

export const authOptions = {
  providers: [
    GithubProvider({
      clientId: '999c4432bb02ef7f57ac',
      clientSecret: 'e00d2c781010348e024e7f947832b9908b594c60',
    }),
  ],
  secret : 'qwer1234'
};
export default NextAuth(authOptions);

/app/layout.js

상단 nav에 넣어야 하기에 layout.js에 작성

import './globals.css'
import { Inter } from 'next/font/google'
import Link from "next/link";
import {LoginBtn,LogOutBtn} from './LoginBtn'; // 클라이언트컴포넌트로 불러오기
import { getServerSession } from 'next-auth'; // 유저정보 불러올 때 사용
import { authOptions } from '@/pages/api/auth/[...nextauth]'; // 유저정보 불러올 때 사용


const inter = Inter({ subsets: ['latin'] })

export const metadata = {
  title: 'Create Next App',
  description: 'Generated by create next app',
}

export default async function RootLayout({ children }) {
  let session = await getServerSession(authOptions) // 로그인정보 출력
  console.log(session)
  return (
    <html lang="en">
      <body className={inter.className}>
      <div className="navbar">
    <Link href="/" className="logo">Appleforum</Link>
    <Link href="/list">List</Link>
    {
    session
      ? <span>{session.user.name} <LogOutBtn/> </span>
      : <LoginBtn></LoginBtn>
  }
</div>  
        {children}</body>
    </html>
  )
}

/app/LoginBtn.js

클라이언트 컴포넌트로 만든 버튼

'use client'
import {signIn,signOut} from 'next-auth/react'

export function LoginBtn(){
    return (
        <button onClick={()=> {signIn()}}>로그인</button>
    )
}

export function LogOutBtn(){
    return (
      <button onClick={()=>{ signOut() }}>로그아웃</button>
    )
  }