23.04.30

이로운·2023년 4월 30일
0

TIL

목록 보기
5/6

🧐 회원가입 동작 원리

회원기능 동작방식

  1. 유저가 가입하면 아이디, 비번, DB에 저장
  2. 유저가 로그인 시 유저 정보 서버로 보냄
  3. 서버는 DB정보 === 요청 정보라면 입장권 발급

입장권?

유저가 로그인을 하면 쿠키에 입장권을 저장시켜둠

쿠키는 GET/POST 요청시 자동으로 서버에 전송을 함

세션방식

  1. 유저 로그인하면 정보 DB에 정보 기록
  2. 우저에게 입장권 발급할때 session id 적어서 보냄

장 : 매번 서버에 요청할때마다 DB를 조회해서 엄격하게 체크 가능

단 : DB 부담 심해짐

해결법 : 유저가 많은 사이트 들은 Redis 같은 DB를 사용

토큰 방식(JWT)

  1. 유저가 로그인하면 유저 정보 보냄 DB에 저장하는건 없음

장 : DB부담 적음, 유저가 많은 사이트들이 주로 사용함

단 : 유저의 JWT를 훔쳐가면 막을 수 있는 방법이 없음

OAuth

로그인 방법중 하나임, 예를 들자면 소셜 로그인

유저의 A사이트의 사용 권한을 B사이트를 운영하는 운영자가 잠깐 빌리는것

🧐 소셜 로그인하기 (깃허브)

페북 구글도 비슷한 방법으로 하면 된다

Github.com 로그인하면 우측상단 Settings -> Developer settings -> New OAuth app

어플리케이션 하나 만든다

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

export const authOptions = {
  providers: [
    GithubProvider({
      clientId: 'Github에서 발급받은ID',
      clientSecret: 'Github에서 발급받은Secret',
    }),
  ],
  secret : 'jwt생성시쓰는암호'
};
export default NextAuth(authOptions);

next.auth가 하라는대로 코드를 짜면 된다. jwt 암호는 그냥 원하는거 적자

🧐 signIn

넥스트는 signIn이라는 함수를 제공한다 이걸 사용하면 만들어져 있는 로그인 페이지에 들어갈 수 있다

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

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

🧐 유저 정보 출력하기

  1. client 컴포넌트
'use client'

import { SessionProvider } from "next-auth/react"

export default function Layout({ children }){
  return (
    <SessionProvider>
      {children}
    </SessionProvider>
  )
}

이렇게 컴포넌트를 만들어서 SessionProvider안에 넣는다 children으로 넣고

let session  = useSession();

원하는 곳에 useSession()을 변수에 할당해서 출력하면 된다

보통은 서버 컴포넌트에서 유저정보 가져와서 보여주는게 낫다 왜냐하면 useSession은 랜더링이 끝나고 출력을 하기 때문에 조금 늦게 실행된다

  1. server 컴포넌트
export default function Page(){
  let session = await getServerSession(authOptions)
  if (session) {
    console.log(session)
  }

🧐 DB adapter

유저의 로그인 상태를 엄격하게 관리하고 싶으면 사용하자

  1. 첫 로그인시 자동으로 유저를 회원가입 시켜서 회원정보 보관
  2. 로그인시 자동으로 유저가 언제 로그인 했는지 세션 정보 db에 보관
  3. 서버에서 유저 정보가 없으면 db에서 가져옴 (jwt에서 가져오지 않음)
  4. 로그아웃시 유저 세션 정보는 db에서 삭제

설치

npm install @next-auth/mongodb-adapter

auth 파일에 코드 추가

export const authOptions = {
  providers: [
    GithubProvider({
      clientId: 'Github에서발급받은ID',
      clientSecret: 'Github에서발급받은Secret',
    }),
  ],
  secret : '어쩌구'
  adapter : MongoDBAdapter(connectDB), //추가함
};

🧐 회원 기능이 들어간 게시글 페이지

글 발행시 글쓴이에 대한 정보도 함께 저장하면 됨

let session = await getServerSession(요청, 응답, authOptions)

서버 기능 안에서 유저 정보를 이렇게 출력한다

출력을 확인한 후에

if (session) {
    요청.body.author = session.user.email
  }

요청이

맞으면 email을 author로 해달라고 할당을 하고 넣으면 된다

응용

게시글 작성자에 관한 validation을 할때 session 변수에 정보를 담고 만약 작성자가 작성한글만 삭제 시키고 싶다면 그 정보의 유저 정보와 글의 유저 정보가 같을때 삭제 시키면 된다.

🧐 아이디/비번으로 회원가입하기 구현

비밀번호 암호화 시키는 라이브러리

npm install bcrypt
import { connectDB } from "@/util/database";
import bcrypt from "bcrypt";

export default async function handler(요청, 응답) {
  if (요청.method === "POST") {
			// 숫자 10은 숫자별로 암호화 정도를 나타냄
      const hash = await bcrypt.hash(요청.body.password, 10);
			// body의 password 부분을 hash로 바꿔줌
      요청.body.password = hash;

      let db = (await connectDB).db('forum');
			// user_cred 라는 컬렉션에 추가
      await db.collection('user_cred').insertOne(요청.body);
      응답.status(200).json('성공');
  }
};

응용

.env 파일 사용하기

보관할 문자 같은것 (시크릿 코드) 같은거를 잠가놓자

예시

NEXTAUTH_SECRET='secretkey1234'

이렇게 적어놓고

secret: process.env.NEXTAUTH_SECRET

env에 적은 파일을 가져다 쓰면 된다 이러면 소스코드를 보더라도 시크릿 키를 알수가 없다

profile
이름 값 하는 개발자가 꿈인 사람

0개의 댓글