Next-auth 소셜 로그인 구현 과정(1)

0
post-thumbnail
post-custom-banner

Next-auth 세팅

1️⃣ 설치

	> yarn add next-auth

2️⃣ .env 파일에 NEXTAUTH_URL, NEXTAUTH_SECRET 환경변수 추가

	> NEXTAUTH_URL=http://localhost:3000
    
    > NEXTAUTH_SECRET은 랜덤한 string 값으로 설정 : openssl rand -base64 24

3️⃣ API Route 추가

  • 발급받은 인증 공급자의 client_id와 client_secret을 .env파일에 설정
  • api/auth/[...nextauth].ts 파일 생성 후 원하는 인증 공급자(Provider) 및 옵션 설정
import NextAuth from "next-auth"
import GoogleProvider from "next-auth/providers/google"

export const authOptions = {
  // Configure one or more authentication providers
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
    // ...add more providers here
  ],
}
export default NextAuth(authOptions)

4️⃣ 최상위 파일에서 Session Provider로 전체 앱 감싸기

// pages/_app.tsx
import { SessionProvider } from "next-auth/react"
export default function App({
  Component,
  pageProps: { session, ...pageProps },
}) {
  return (
    <SessionProvider session={session}>
      <Component {...pageProps} />
    </SessionProvider>
  )
}

5️⃣ useSession() 및 singIn 또는 signOut과 같은 인증 훅 적용

export default function LoginPage() {
  const { status, data: session } = useSession();
  const router = useRouter();

  useEffect(() => {
    if (status === "authenticated") {
      router.replace("/");
    }
  }, [router, status]);

  return (
     <button
         type="button"
         className="text-white flex gap-2 bg-[#4285f4] hover:bg-[#4285f4]/90 font-medium rounded-lg w-full px-5 py-4 text-center items-center justify-center"
          onClick={() => signIn("google", { callbackUrl: "/" })}
      >
          <AiOutlineGoogle className="w-6 h-6" />
          Sign in With Google
      </button>





Prisma Adapter 세팅

1️⃣ 설치

> yarn add @auth/prisma-adapter

2️⃣ next-auth 파일에 정의

➰ Prisma Adapter란 ?
Next-auth로 로그인 또는 회원가입한 사용자들의 계정 정보와 세션/토큰 정보를 저장할 수 있도록 연동하는 것 (자동으로 prisma에 맞게 데이터 생성 가능)

import NextAuth from "next-auth"
import Providers from "next-auth/providers"
import { PrismaAdapter } from "@next-auth/prisma-adapter"
import { PrismaClient } from "@prisma/client"

const prisma = new PrismaClient()

export default NextAuth({
  providers: [
    Providers.Google({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
  ],
  adapter: PrismaAdapter(prisma),
})

3️⃣ prisma.schema 파일에 스키마 정의

model Account {
id String @id @default(cuid())
userId Int
type String
provider String
providerAccountId String
refresh_token String? @db.Text
refresh_token_expires_in Int?
access_token String? @db.Text
expires_at Int?
token_type String?
scope String?
id_token String? @db.Text
session_state String?

user User @relation(fields: [userId], references: [id], onDelete: Cascade)

@@unique([provider, providerAccountId])
}

model User {
id Int @id @default(autoincrement())
email String @unique
name String?
emailVerified DateTime?
image String?
accounts Account[]
sessions Session[]
likes Like[]
comments Comment[]
}

model Session {
id String @id @default(cuid())
sessionToken String @unique
userId Int
expires DateTime
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
}

model VerificationToken {
identifier String
token String @unique
expires DateTime

@@unique([identifier, token])
}

3️⃣.5️⃣ migrate

> npx prisma migrate dev

4️⃣ Middleware 세팅

https://next-auth.js.org/configuration/nextjs#middleware

  • 특정 경로에서 항상 로그인을 해야하는 경우 middleware를 통해서 해당 페이지에 접근 권한을 제한시킬 수 있다.(보안 향상)
  • .env 파일에 NEXTAUTH_SECRET을 생성 후 반드시 로그인이 필요한 페이지 경로를 Middleware를 통해 정의(/src/middleware.ts)
export { default } from "next-auth/middleware"

export const config = { matcher: ["/users/mypage", "/stores/new", "/stores/:id/edit", "/users/likes"] }

💡
공식문서 참고

post-custom-banner

0개의 댓글