1. next-auth 라이브러리 다운로드 받고 데이터베이스 설정하기
1-1. next-auth 라이브러리 다운로드
우선 NextAuth 패키지를 설치해야 합니다. 터미널에서 아래 명령어를 실행하세요:
npm install next-auth
yarn add next-auth
1-2. mongodb 데이터베이스 설치 및 설정하기
MongoDB와 NextAuth를 연결하려면, 아래 패키지를 추가로 설치해야 합니다:
npm install mongodb @next-auth/mongodb-adapter
또는 yarn을 사용한다면:
yarn add mongodb @next-auth/mongodb-adapter
1-3. mongodb 페이지에서 데이터베이스 생성 및 콜렉션 생성하기

- 제가 사용한 데이터베이스는 StellarLink 입니다.
- 원하는 이름으로 생성하면 됩니다.

- Network Accecss 탭에서 사용할 주소를 입력하여 줍니다.
1-4. mongodb 연결 코드 작성하기
프로젝트 상단에 /util/database.ts 파일을 생성하고 MongoDB 연결 코드를 작성합니다.
import { MongoClient } from 'mongodb';
const url = process.env.DATABASE_KEY as string;
if (!url) {
throw new Error('Please define the DATABASE_KEY environment variable in .env');
}
// TypeScript에서 글로벌 객체 정의
declare global {
// 글로벌 변수 `_mongo`가 Node.js 전역에 존재하지 않는다면 선언
// Node.js 환경에만 존재하도록 정의
var _mongo: Promise<MongoClient> | undefined;
}
let connectDB: Promise<MongoClient>;
if (process.env.NODE_ENV === 'development') {
// 개발 환경에서 전역 객체를 재사용
if (!global._mongo) {
global._mongo = new MongoClient(url).connect();
}
connectDB = global._mongo;
} else {
// 프로덕션 환경에서는 새로 연결
connectDB = new MongoClient(url).connect();
}
export { connectDB };
- process.env.DATABASE_KEY 는 .env 파일에 저장된 값입니다.
이때,
process.env. 어쩌구
인 경우 환경변수 파일에 작성되어 있다는 뜻입니다.
이는 보통 보호해야하는 값일 경우 사용됩니다. 추후에 배포할때도 신경써서 작성해야합니다.
프로젝트 상단에 .env 파일을 만들어서

다음과 같이 적습니다.
해당 키는 몽고 디비 사이트에서 얻을 수 있습니다.

- Overview 에서 Clusters 의 Connect 버튼을 찾아 클릭합니다.

- Drivers 를 클릭합니다.

- 빨간 부분의 값을 .env 파일의
로 넣으시면 됩니다.
이때, admin:<db_password> 의 db_password부분을 제대로 바꿔서 넣습니다!
2. NextAuth 설정 파일 생성하기 (api 제작하기)
2-1. /pages/api/auth/[...nextauth].ts 파일을 생성하기
import { MongoDBAdapter } from "@next-auth/mongodb-adapter";
import NextAuth from "next-auth";
import GithubProvider from "next-auth/providers/github";
import {connectDB} from '@/util/database';
import CredentialsProvider from "next-auth/providers/credentials";
import GoogleProvider from "next-auth/providers/google"; // GoogleProvider 추가
import DiscordProvider from "next-auth/providers/discord";
export const authOptions = {
providers: [
// GitHub 로그인
GithubProvider({
clientId: process.env.GITHUB_CLIENT_ID,
clientSecret: process.env.GITHUB_CLIENT_SECRET,
}),
// Google 로그인
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
}),
//Discord 로그인
DiscordProvider({
clientId: process.env.DISCORD_CLIENT_ID || "",
clientSecret: process.env.DISCORD_CLIENT_SECRET || "",
}),
CredentialsProvider({
//1. 로그인페이지 폼 자동생성해주는 코드
name: "credentials",
credentials: {
email: { label: "email", type: "text" },
password: { label: "password", type: "password" },
},
//2. 로그인요청시 실행되는코드
//직접 DB에서 아이디,비번 비교하고
//아이디,비번 맞으면 return 결과, 틀리면 return null 해야함
async authorize(credentials) {
let db = (await connectDB).db('StellarLink');
let user = await db.collection('user_cred').findOne({email : credentials.email})
if (!user) {
console.log('해당 이메일은 없음');
return null
}
const bcrypt = require('bcryptjs');
const isValidPassword = await bcrypt.compare(credentials.password, user.password);
console.log(`isValidPassword: `, isValidPassword)
if (!isValidPassword) {
console.log('비밀번호 틀림');
return null;
}
// 로그인 성공
console.log('로그인 성공', user);
return user;
}
})
],
//3. jwt 써놔야 잘됩니다 + jwt 만료일설정
session: {
strategy: 'jwt',
maxAge: 30 * 24 * 60 * 60 //30일
},
callbacks: {
//4. jwt 만들 때 실행되는 코드
//user변수는 DB의 유저정보담겨있고 token.user에 뭐 저장하면 jwt에 들어갑니다.
jwt: async ({ token, user }) => {
if (user) {
token.user = {};
token.user.name = user.name
token.user.email = user.email
}
return token;
},
//5. 유저 세션이 조회될 때 마다 실행되는 코드
session: async ({ session, token }) => {
session.user = token.user;
return session;
},
},
secret : process.env.NEXTAUTH_SECRET,
adapter:MongoDBAdapter(connectDB)
};
export default NextAuth(authOptions);
- import GoogleProvider from "next-auth/providers/google"; 를 통해 구글 로그인을 설정할 수 있습니다.
- import GithubProvider from "next-auth/providers/github"; 를 통해 github 로그인을 설정할 수 있습니다.
- import DiscordProvider from "next-auth/providers/discord"; 를 통해 디스코드 로그인을 설정할 수 있습니다.
- import CredentialsProvider from "next-auth/providers/credentials";를 통해 로컬 로그인을 구현할 수 있습니다.
2-1-1. 여기서 secret : process.env.NEXTAUTH_SECRET?
1. JWT 토큰 서명
NextAuth는 기본적으로 JWT (JSON Web Token)을 사용하여 세션 정보를 저장합니다.
JWT에는 중요한 사용자 정보가 포함될 수 있으므로, 서명을 통해 토큰의 무결성을 보장해야 합니다.
NEXTAUTH_SECRET은 이러한 JWT의 서명을 위한 비밀 키로 사용됩니다.
이 키가 설정되지 않으면 NextAuth는 JWT 서명 및 검증이 불가능합니다.
2. CSRF 보호
NextAuth는 CSRF(Cross-Site Request Forgery) 공격을 방지하기 위해 여러 보안 메커니즘을 사용합니다.
NEXTAUTH_SECRET은 CSRF 방지를 위한 토큰 생성 및 검증에도 사용됩니다.
3. 암호화된 쿠키 데이터 보호
NextAuth는 쿠키를 통해 세션 정보를 전달합니다.
NEXTAUTH_SECRET은 쿠키에 저장된 데이터를 암호화하고 복호화하는 데 사용됩니다.
4. 개발 환경과 운영 환경
- 개발 환경:
NEXTAUTH_SECRET이 설정되지 않은 경우 NextAuth는 자동으로 무작위 키를 생성합니다.
하지만 이는 개발 환경에서만 사용해야 하며, 운영 환경에서는 절대 사용하면 안 됩니다. - 운영 환경:
반드시 .env 파일에 안전한 고유 문자열을 설정해야 합니다.
예시:NEXTAUTH_SECRET는 강력한 임의 문자열이어야 하며, Random Key Generator와 같은 도구를 통해 생성할 수 있습니다. -
코드 복사NEXTAUTH_SECRET=your-secure-random-secret
- env
5. 설정하지 않으면 생기는 문제
- 토큰 서명 및 검증 실패로 인해 JWT 기반 인증이 동작하지 않을 수 있습니다.
- CSRF 보호 및 쿠키 암호화가 제대로 이루어지지 않아 보안 취약점이 생깁니다.
- NextAuth가 오류 메시지를 표시하며 시작되지 않을 수 있습니다.
각각의 키는 각 깃허브, 구글, 디스코드에서 받을 수 있습니다.
3. 깃허브, 구글, 디스코드 각각의 CLIENT_ID, CLIENT_SECRET 받기
3-1. 깃허브에서 CLIENT_ID, CLIENT_SECRET 받기

- settings 에 들어갑니다.

- 맨 아래로 내려보면 왼쪽 제일 하단에 Developer settings 가 있습니다.

- OAuth Apps 를 클릭하고 새로운 New OAuth App을 생성합니다.

- 자신의 홈페이지 URL를 적습니다. 이때, 로컬에서 개발중이라면 저와 같이, 아니라면 실제 도메인 포함된 URL를 적어주시면 됩니다.

- 그럼 General 탭에서 바로 Client ID 가 생성이 되는데요, (빨간부분입니다)
- Client secrets 도 받기 위해서는 Generate a new client secret 버튼을 클릭하셔서 인증을 받아야 합니다.

- 저는 패스워드 인증을 선택했고 Confirm 을 클릭합니다.

- 그럼 Client secrets 도 두번째 빨간 박스에 표시됩니다!
- 두개를 모두 .env 파일에 잘 저장해주시면 됩니다.
3-2. 구글 CLIENT_ID, CLIENT_SECRET 받기
https://console.cloud.google.com/welcome?inv=1&invt=Abjq_A&project=stellar-link
Google 클라우드 플랫폼
로그인 Google 클라우드 플랫폼으로 이동
accounts.google.com
해당 사이트에서 진행합니다.

- 프로젝트 선택 창에서 새 프로젝트를 클릭합니다.

- 이름을 작성하고 만들기를 클릭합니다.

-생성된 새로운 프로젝트를 클릭하면 대시보드가 나타납니다.
- API 및 서비스에서 사용자 인증 정보를 클릭합니다.

- 사용자 인증 정보 만들기 버튼을 클릭하고, OAuth 클라이언트 ID 버튼을 클릭합니다.

- 동의 화면 구성을 클릭합니다.

- 새로운 버전이 나왔는지 곧 사라진다고 합니다.
- 새로운 환경으로 이동을 클릭합니다.

- 앱 정보, 대상, 연락처 정보, 동의 를 원하는대로 입력한 후 , 만들기를 클릭합니다.

- 클라이언트 탭에서 클라이언트 만들기를 클릭합니다.
- 이때, 시간이 좀 걸리는지 새로고침 해주면 동의화면 구성하라는 말 없이 잘됩니다.

- 빨간 사각형 부분을 입력 후 만들기를 클릭합니다.

- 그럼 이와 같이 클라이언트 ID 가 보입니다.
- 시크릿 ID 도 얻기위해서는 해당 앱을 클릭하여 들어갑니다.

- 들어가면 빨간 박스에 클라이언트와 시크릿 키 모두 잘 생성되었습니다.
- .env 파일에 잘 저장합니다.
3-3. 디스코드 CLIENT_ID, CLIENT_SECRET 받기 (비교적 간단함!)
https://discord.com/developers/applications
Discord Developer Portal — API Docs for Bots and Developers
Integrate your service with Discord — whether it's a bot or a game or whatever your wildest imagination can come up with.
discord.com
해당 사이트에서 진행합니다.

- New Application 을 해줍니다.

- 이름 잘 작성하고 Create 을 해줍니다.

- OAuth2 에서 Redirects 를 적어줍니다.
-로컬 개발일 경우, http://localhost:3000/api/auth/callback/discord 를 띄어쓰기없이! 잘적어줍니다.

- 아래로 내려 identity, email 을 체크해줍니다.
- 더 필요한게 있으시면 체크하시면 됩니다.
- 그리고 꼭! Save Changes 를 해줘야 합니다.

- 그럼 위에 Client ID 가 도출되어 있습니다.
- Client Secret 을 얻기 위해 Reset Secret 을 해줍니다.

- 위험 하다고 하지만,,, Yest, do it! 합니다.
- 비밀번호로 인증합니다.

- 그럼 두 빨간 박스에 Client ID, Client secret ID 가 제대로 생성되었습니다!
-이를 마찬가지로 .env 파일에 잘 저장합니다!
- 다른 것들보다 비교적 간단하고 쉽습니다!!
4. 로그인 페이지 코드 작성하기
- 저는 다음과 같이 적었습니다.
- 소셜 로그인 일 경우, onClick={() => signIn('google', { callbackUrl: '/chat' })}
signIn 함수
를 통해 쉽게 처리할 수 있습니다.
- 로컬 로그인의 경우
해당 함수를 통해 credentials
로 signIn 해줍니다.
이렇게 모든 작업이 완료되었습니다!
제 글이 조금이라도 도움이 되길 바라며 정성껏 작성하였습니다.
공감부탁드려요!

'웹개발' 카테고리의 다른 글
[React] Redux (중앙 상태 관리 라이브러리)를 채팅 웹앱에 실제로 적용하기 (1) | 2024.12.27 |
---|---|
[Next.js] 세션정보 변경 후 프론트엔드 쪽에 바로 업데이트 되지 않을 때 (feat. authOptions) (2) | 2024.12.20 |
[React-Three-Fiber] 같은 3D 모델 여러개를 Canvas에 배치하기(https://sketchfab.com/ 에서 gltf 다운 및 사용하기) (0) | 2024.12.07 |
[Next.js] React-Three-fiber 을 사용하여 3D 모델 프로젝트에 추가 및 애니메이션 적용하기 (0) | 2024.12.06 |
[Next.js] 포트폴리오에서 누군가 나에게 이메일을 보낼 수 있는 기능 개발하기 (0) | 2024.11.27 |