[NJ(300~305)]NextAuth.js 설치 및 db 연결, api 작성

이유정·2024년 4월 21일
0

Next.js (pages router)

목록 보기
35/42

JSON Web Tokens

01. Issuer Data
: 토큰이 생성될 때 server에 의해 토큰에 자동으로 추가되는 data

  • 토큰을 생성할 때 이용한 서드 파티 패키지에 의해 미리 구성되는 meta data.

02. Custom Data
: 토큰에 커스텀 data를 추가할 수 있음. (사용자 정보 같은것)

03. Secret Signing Key
: 비밀키를 서버에 설정한다.

  • client는 그 키를 절대 못 봄
  • 해당 키가 있어야만 server가 인정하는 유효 토큰을 생성
  • server만이 그 키를 알고 있음.

third-party-package를 사용해 이런 조각을 하나로 결합한다.
=> 이 모든 data를 포함하는 임의의 문자열 생성
=> 해당 key로 서명해서 token 생성 (서명은 암호화를 뜻하지 않음.)
=> 아주 긴 문장열 JSON 웹 토큰

JSON Web Tokens

  • json web token은 암호화되지 않는다.
  • key가 없어도 열어서 내부의 data를 읽을 수 있음.
  • 키는 주어진 server가 그 token을 생성했다는 사실만 증명
  • key를 몰라도 token 내용은 읽을 수 있음.
  • 물론, key는 토큰에 포함되지 않는다. => 그러니, 토큰을 열어도 키를 읽을 수는 없음.
  • 토큰은 client-side-browser에 저장되어 server의 보호된 resource에 대한 요청에 첨부된다.
    ex) 비밀번호를 바꾸려고 할 때, 나가는 요청에는 예전 비밀 번호 + 새 비밀번호 + 해당 토큰

  • 그리고 그 토큰은 server에서 유효성 검사를 받는다.
    "나만 알고 있는 서명키가 있는데 이걸로 이 토큰 만들 수 있나요? "
    만약 yes => server는 유효함
    만약 no => 무효가 되어 access 거부됨

  • 이 모든 것을 백지부터 구축할 필요 x

  • 토큰 생성 및 유효성 검사 등은 안전한 third party package에 맡길 수 있음.

NextAuth.js

인증 구현하는데 쓰이는 package => NextAuth.js

  • 아주 쉽고, 간단함
  • 작성자를 위한 다양한 인증 종류를 지원
    ex) 이메일 & 비밀번호 , 소셜 로그인

    공식문서에 보면, Provider 칸에 해당 공급자로 인증을 구현하는 방법이 나온다.

설치

npm i next-auth 
  • server side, client side 기능 둘다 지원
  • 일부 API 라우트에서 이를 사용자 로그인 여부를 확인하는데 사용할 수 있음.
  • 컴포넌트가 같은 작업을 수행하게도 만들 수 있다. (사용자가 login 및 인증됐는지에 대한 답은 servier side의 보호된 resource api 라우트 뿐만 아니라 client side component에도 필요하다. )
  • 사용자가 인증되었는지 여부에 따라 각기 다른 사용자 interface를 표시할 수 있음.
  • server side 및 client side 유효성 검사 둘 모두 수행할 수 있음.
  • 인증 token, json web token을 생성하는 것도 도와줌
  • 하지만, 사용자 생성 관리는 안해줌. (우리만의 논리가 필요)
  • 다양한 db를 지원하긴 하지만, 대체로 다른 인증 메서드를 위한 거라서,, 자체 사용자 계정을 사용할 경우에는 자체적인 회원가입 API 라우트와 사용자 인증 논리를 가져와야 한다. (강의 305)

논리 구성

Next.auth는 스스로 작업을 수행하지 않기 때문에,,
사용자 계정에 대한 인증 체계를 구축하고자 할 때 Next.auth 기능을 쓰기 전에
먼저 사용자를 추가하는 논리를 구성해야 한다.
그래야만,,,
NextAuth.js에서 그 사용자에 대해 인증을 진행하고 사용자에게서 Token을 가져온다.
하지만,
사용자를 생성하려면 먼저 논리가 있어야 한다.

먼저, 개발 서버를 가동하라.

npm run dev 

우리는 API 라우트를 통해 이메일 & 비밀번호 를 포함하는 요청이 새로운 계정이 생성될 때 login page에서 전송되어 DB에 그 정보를 저장되게끔 하려고 한다.

사용자 DATA는 => MongoDB를 사용하자.

API 라우트를 생성해야 한다.
/pages/api 폴더에서 파일 생성


mongodb 설치

설치한 다음

npm run dev

그래야 db에 정상적으로 연결된다.

db에 연결할 때는 여러가지 함수와 api 라우트를 거쳐야 하기 때문에 공통된 논리를 사용하기 위해 프로젝트의 root 수준에 lib라는 폴더를 만들자.

이 파일에서 db로 연결하는 논리를 구성할 것.


MongoDB Atlas에서 생성된 클러스터를 통해 문자열을 가져와야 한다.

db 파일에서 db에 연결하는 함수를 만들어서 export 해줬다.


signup 파일에서 db 접근할 수 있게 됐다.

새로운 사용자를 생성하여 db 내 컬렉션에 정보를 저장하자.


mongoDB는 문서의 컬렉션으로 이루어져 있고, 각 사용자는 하나의 문서이고, 그러한 문서가 모여 컬렉션이 되는 것이다. => 컬렉션에 접근하게 하는 DB의 collection 메서드를 호출하면 모든 컬렉션을 사용할 수 있게 된다. 그리고 컬렉션이 없는 경우에는 바로 생성해준다.


제출된 사용자 data를 가져 오려면 req,res 객체를 받아야 한다.
API 라우트가 들어오는 요청에 접근해서 응답 객체를 사용해 응답을 보낼 수 있다.

들어오는 data를 추출하는 논리를 먼저 구성하는 것이 좋다.
=> 그래야 유효한 data가 있을 때만 작업이 진행된다.


req.body 에 접근해서 data를 추출하자.

그리고, auth-form 파일에서 전송되는 요청에 email, password를 포함해서 새로운 사용자를 생성할 때 API 라우트로 전송되도록 하자.


그 전에, 이 데이터가 유효한지 확인하는 절차도 필요하다.

  • 이메일 주소에 @ 가 포함되어 있어야 한다.
  • password 길이가 7이상 이어야 한다.


조건에 부합했을 때 data로 들어온 email과 password를 해당 users 컬렉션에 삽입한다.

그런데, db에 저장할 비밀번호는 그대로 저장해서는 안된다.
db 해킹당하면 사용자 정보가 그대로 노출된다.
보안성을 높이기 위해서, db에 비번을 그대로 저장하지 않고 해독할 수 없도록 암호화한 다음에 저장해야 한다.


비밀번호를 암호화하기 위해서는 third-party 패키지를 설치해야 한다.
사실, 비밀번호뿐만 아니라 어떤 데이터도 암호화할 수 있지만 여기에는 비밀번호에 쓸 것임.
ts를 위해 이것도 설치

npm i --save-dev @types/bcryptjs

인증과 관련된 유틸리티 메서드를 정의해보자.
lib 폴더에 auth.tsx 파일을 생성

password 값이 들어오면 암호화 하는 함수다.

두번째 인수에는 SaltRound 값을 정한다.

  • 비밀번호의 암호화 정도를 결정하는 함수
  • 값이 클수록 함수 완료가 오래걸리고 숫자가 작을 수록 비밀번호의 보완성이 떨어진다.


이렇게 하면 hash 함수가 프로미스를 반환하면서 암호화된 비밀번호를 내보낸다.


hashedPassword 생성


그리고 비밀번호를 만들어놓은 함수로 암호화하고, password의 값으로 넣어준다.


insertOne도 프로미스를 반환하니 이것도 역시 await으로 대기하도록 하고.
이 함수가 처리되고 나면 자동으로 생성된 사용자 id에 접근할 수 잇고,
그걸 이용해 db에 사용자를 저장할 수 있게 된다.

profile
팀에 기여하고, 개발자 생태계에 기여하는 엔지니어로

0개의 댓글