업체별 인증코드 발급받기
구글
카카오 (prisma 적용 연구중)
더보기
https://developers.kakao.com/console/app
링크에 접속하여 카카오 로그인 서비스를 사용할 애플리케이션을 추가합니다.
저는 사용할 이미지가 아직 없어서 앱 아이콘을 제외하고 모두 채워주었습니다.
앱 키에서 제공하는 Javascript 키를 ClientID 로 사용하게 됩니다.
플랫폼에서 Web 플랫폼 등록을 진행합니다.
사이트 도메인을 입력해줍니다. 저는 실제 도메인과 로컬 주소 모두를 입력해두었습니다.
카카오 로그인에서 카카오 로그인을 활성화 시키고 Redirect URL을 추가합니다.
Redirect URL은 /api/auth/callback/kakao 로 작성해주셔야 원활하게 동작합니다.
동의항목에서 필요한 정보의 동의 상태를 변경합니다. 저는 우선 닉네임만 활성화 시켰습니다.
보안에서 Client Secret을 발급받습니다. clientSecret 키 정보도 clientID와 함께 인증을 위해 사용됩니다.
** Prisma로 DB를 사용중인 상태라고 생각하고 작성하겠습니다 **
https://fjdkslvn.tistory.com/153
[Next.js] Prisma로 기존 MYSQL 연동하기
1. 모듈설치npm install prisma 2. scheme.prisma 파일 생성npx prisma initsrc와 동일한 위치로 prisma 폴더가 생성되고 scheme.prisma 파일이 생성됩니다.provider를 mysql로 변경하고 url에 DATABASE_URL 환경변수를 설
fjdkslvn.tistory.com
1. next-auth 및 필요한 prisma 모듈 설치
npm install next-auth @types/next-auth @next-auth/prisma-adapter
2. schema.prisma 업데이트 (MYSQL)
model User {
id String @id @default(uuid())
name String
email String? @unique
emailVerified DateTime? @map("email_verified")
image String?
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
accounts Account[]
favorites favorites[]
sessions Session[]
@@map("users")
}
model Account {
id String @id @default(cuid())
userId String @map("user_id")
type String?
provider String
providerAccountId String @map("provider_account_id")
token_type String?
refresh_token String? @db.Text
access_token String? @db.Text
expires_at Int?
scope String?
id_token String? @db.Text
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
@@unique([provider, providerAccountId])
@@index([userId], map: "accounts_user_id_fkey")
@@map("accounts")
}
model Session {
id String @id @default(cuid())
userId String? @map("user_id")
sessionToken String @unique @map("session_token")
accessToken String? @map("access_token") @db.Text
expires DateTime
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
user User? @relation(fields: [userId], references: [id], onDelete: Cascade)
@@index([userId], map: "sessions_user_id_fkey")
@@map("sessions")
}
model VerificationRequest {
id String @id @default(cuid())
identifier String
token String @unique
expires DateTime
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@unique([identifier, token])
}
schema.prisma 파일에 사용자 관련 모델을 추가합니다.
prisma 공식 페이지에서 안내한 형태 그대로 사용하면 p.account.findUnique() 관련 오류가 발생합니다.
오류가 발생하지 않도록 수정된 모델을 사용하시면 좋을것같습니다.
(MYSQL이 아니더라도 같은 오류가 발생하시면 아래 이슈 문서 추천드립니다.)
https://github.com/nextauthjs/next-auth/issues/3815
Invalid `p.account.findUnique()` invocation with prisma · Issue #3815 · nextauthjs/next-auth
Title Invalid p.account.findUnique() invocation with prisma How to reproduce ☕️ next-auth: 4.0.0-beta.7 @next-auth/prisma-adapter: 0.5.2-next.19 /pages/api/[...nextauth].ts import { PrismaAdapter }...
github.com
파일에 모델을 추가하였다면 아래 명령어를 차례대로 실행하여 실제 DB 및 Prisma에 적용될 수 있도록 합니다.
npx prisma db pull
npx prisma migrate diff --from-empty --to-schema-datamodel prisma/schema.prisma --script > prisma/migrations/0_init/migration.sql
이 명령어는 본인의 파일 구조를 확인하시고 실행하시면 됩니다.
npx prisma generate
여기까지 하시면 새로 생성된 모델이 적용됩니다.
3. SessionProvider 적용
AuthProvider 파일을 생성하고 메인 layout.tsx 파일에 적용합니다.
#components > providers > authProvider.tsx
"use client";
import { SessionProvider } from "next-auth/react";
import { ReactNode } from "react";
import { Session } from "next-auth";
type Props = {
session?: Session | null;
children: ReactNode;
};
export default function AuthProvider({ session, children }: Props) {
return <SessionProvider session={session}>{children}</SessionProvider>;
}
# layout.tsx
import type { Metadata } from "next";
import { Noto_Sans_KR } from 'next/font/google';
import "@/styles/globals.css";
import AuthProvider from '@/components/providers/authProvider'
...
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode;
}>) {
return (
<html>
<body className={noto.className}>
<AuthProvider>
{children}
</AuthProvider>
</body>
</html>
);
}
4. auth API 작성
app > api > auth > [...nextauth] > route.ts
import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";
import { PrismaAdapter } from "@next-auth/prisma-adapter"
import { PrismaClient } from "@prisma/client"
const prisma = new PrismaClient()
const handler = NextAuth({
adapter: PrismaAdapter(prisma),
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID || "",
clientSecret: process.env.GOOGLE_CLIENT_SECRET || "",
}),
],
callbacks: {
async jwt({ token, user }) {
return { ...token, ...user };
},
async session({ session, token }) {
session.user = token as any;
return session;
},
},
session: {
strategy: 'jwt'
},
secret: process.env.NEXTAUTH_SECRET
});
export { handler as GET, handler as POST };
app > api > auth > [...nextauth] > route.ts 위치에 위 코드를 작성해줍니다.
PrismaAdapter : prisma에 연결된 DB에서 user 정보를 자동으로 관리하도록 합니다.
provider : google, kakao 등 자동 로그인이 필요한 서비스를 연결할 수 있습니다.
clientId, clientSecret : 인증을 위해 각 서비스 발급받아서 사용하는 정보입니다. (보안상 환경변수로 사용하기 위해 .env에서 불러와 사용합니다.)
jwt, session : user ID를 받아내기 위해 jwt 및 session을 설정합니다.
NEXTAUTH_SECRET : JWT를 암호화하고 이메일 확인 토큰을 해시하는데 사용됩니다. (배포시 필수)
NEXTAUTH_SECRET 생성 명령어
// 터미널에 입력해서 NEXTAUTH_SECRET를 얻을 수 있습니다.
openssl rand -base64 32
5. Session 타입 확장
import { DefaultSession } from "next-auth";
declare module "next-auth" {
interface Session {
user?: {
id?: string;
role?: string;
} & DefaultSession["user"];
}
}
각 user를 식별할 수 있는 id 정보를 받기 위해서 타입 확장을 진행합니다.
6. 로그인
'use client'
import { useEffect } from 'react';
import { useSession, signIn, signOut } from "next-auth/react"
const Navbar: React.FC = () => {
const { data: session } = useSession();
useEffect(() => {
console.log(session?.user?.id);
console.log(session?.user?.name);
console.log(session?.user?.email);
},[session])
return (
<div>
{session
?<>
<div>{`${session.user?.name}님`}</div>
<div onClick={() => signOut()}>로그아웃</div>
</>
:<div onClick={() => signIn()}>로그인</div>}
</div>
);
};
export default Navbar;
useSession : session을 통해 로그인 한 사용자의 정보를 받아낼 수 있습니다.
signIn, signOut : 로그인, 로그아웃을 할 수 있습니다.
[공식문서 및 참고문서]
https://next-auth.js.org/getting-started/example
Getting Started | NextAuth.js
The example code below describes how to add authentication to a Next.js app.
next-auth.js.org
https://next-auth.js.org/configuration/initialization#route-handlers-app
Initialization | NextAuth.js
The main entry point of NextAuth.js is the NextAuth method that you import from next-auth. It handles different types of requests, as defined in the REST API section.
next-auth.js.org
https://powerku.tistory.com/312
next-auth 이용해서 10분만에 소셜 로그인 구현 하기
next-auth란? next-auth는 Next.js 프로젝트에서 소셜 로그인을 간단하게 구현할 수 있는 라이브러리 입니다. 국내에서는 구글, 카카오, 네이버, 페이스북, 애플 등 다양한 소셜 로그인을 이용하고 사용
powerku.tistory.com
https://blog.teamelysium.kr/nextjs-auth
NextAuth.js로 간편 로그인 기능 구현하기
팀엘리시움 블로그에서 제품, 테크, 고객사례, 뉴스 등의 이야기를 확인해보세요.
blog.teamelysium.kr
https://velog.io/@dosomething/Next-auth-%EB%A5%BC-%EC%9D%B4%EC%9A%A9%ED%95%9C-%EB%A1%9C%EA%B7%B8%EC%9D%B8-%EA%B5%AC%ED%98%84
Next-auth 를 이용한 로그인 구현
next-auth 라이브러리를 이용해 로그인을 구현한 내용에 대해 공유합니다.
velog.io