NextAuth.js kullanımı | Next.js 13
Projelerimizde authentication işlemleri için bir kaç farklı yöntem kullanabiliyoruz. Peki hiç OAuth süreçlerini kullandınız mı ? Örneğin kullanıcılarınıza Google ile giriş yapma kolaylığı sağladınız mı ? Dilerseniz OAuth nedir, önce onu tanımlayalım. Bunun için ChatGPT’den kısa bir açıklama isteyelim 🤖
Sanırım bu açıklama gayet açıklayıcı ve yeterli. Ben bu yazımda Next.js projelerimizde OAuth protokolünü basitçe uygulamamızı sağlayan NextAuth.js paketini anlatacağım ve basit bir kullanım örneği yapacağım.
Yazı sonunda geliştirmiş olacağımız projeyi şimdiden incelemek isterseniz: NextAuth.js kullanım örneği | Next.js 13 (app directory)
NextAuth.js
NextAuth.js, açık kaynaklı bir kimlik doğrulama ve yetkilendirme kütüphanesidir. Bu kütüphane bize aklınıza gelebilecek bir çok servisin provider’ını barındırıyor. Google, Apple, Facebook, Github, Twitter gibi…
Biz bugün Google provider kullanarak örnek bir Next.js projesi geliştireceğiz. Hazırsanız başlayalım. 🚀
Next.js projesi oluşturma adımını geçiyorum, ben bu projemde typescript, tailwind kullanacağım. Önemli kısım ise pages klasörüm olmayacak, app klasörümde geliştirmemi yapacağım.
Projeye NextAuth.js Ekleme
Kullandığınız paket yöneticisine göre komutlar değişecektir. Ben yarn kullanıyorum, siz npm veya pnpm tercih edebilirsiniz. 🤷
yarn add next-auth
Provider Ekleme Ayarları
Paketimizi projemize yükledikten sonra bir API Route eklememiz gerekiyor.
Burada önemli kısım projenizdeki pages klasörünün varlığı. Eğer projenizde pages klasörü varsa bu klasörün altına /api/auth/ yollarını ekleyip […nextauth].js isimli dosya oluşturmalısınız. Yani dosya yolu şu şekilde olmalıdır:
pages/api/auth/[…nextauth].js
Fakat projenizde pages klasörü yoksa app klasörünün altına yine aynı yolları ekleyip route.ts (veya .js) isimli dosya oluşturmalısınız. Yani dosya yolu şu şekilde olmalıdır:
app/api/auth/[…nextauth]/route.ts
Ben belirttiğim gibi pages klasörü kullanmadığım için app klasörümün altında oluşturdum api route’umu. Şimdi ise dosyamızın içini dolduralım.
import NextAuth from "next-auth"
import GoogleProvider from "next-auth/providers/google"
if (!process.env.GOOGLE_CLIENT_ID || !process.env.GOOGLE_CLIENT_SECRET) {
throw new Error("Google client ID and client secret are required.")
}
const handler = NextAuth({
providers: [
GoogleProvider({
clientId: process.env.GOOGLE_CLIENT_ID,
clientSecret: process.env.GOOGLE_CLIENT_SECRET,
}),
],
})
export { handler as GET, handler as POST }
Burada paketin bize sağladığı kolaylıkla GoogleProvider’ı import ettik ve içine clientId ve clientSecret değerlerini girdik. Peki bu değerleri nereden alacağız gelin sırada buna bakalım.
Google Provider Ayarları
Öncelikle bunun için Firebase kullanacağız. Buradan yeni proje oluşturacağız (add project). Açılan ekranda projemiz için bir isim verelim, ardından her şeyi varsayılan olarak bırakarak oluşturma işlemini tamamlayalım.
Projemiz oluştuktan sonra bizi panele yönlendirecektir. Sol taraftaki araç çubuğundan Build > Authentication tıklayalım ve Get Started butonu ile provider seçme ekranına girelim.
Buradan Google’ı seçelim ve Enable seçeneğini açalım ayrıca Support e-e-mail for project kısmında e-posta hesabınızı seçmeyi unutmayın. Kaydettikten sonra yönlendirilen ekranda provider’ımızın sağında bulunan butona (kalem) tıklayalım (Edit configuration).
Son olarak Web SDK configuration menüsüne tıklayarak clientId ve clientSecret değerlerimizi görelim.
Environment Ekleme
Bu değerleri projemizde Google provider’ımıza vermiştik hatırlarsanız fakat process.env. şeklinde vermiştik. Yani bu değerleri environment dosyamızından almasını istemiştik, şimdi bu dosyayı oluşturalım. Projemizin ana dizininde .env.local isimli dosya oluşturarak içine clientId ve clientSecret değerlerini girelim.
Session Provider Ekleme
Projemize Google provider’ı tanımladıktan sonra yapmamız gereken şey tüm uygulamayı NextAuth.js’ten import edeceğimiz SessionProvider ile sarmalamak. Bunun için bir component oluşturuyorum Provider isimli. Benim projemde yolu şu şekilde:
components/provider/index.tsx
Component’imizde children alıp import ettiğimiz SessionProvider’ın içinde return ediyoruz. SessionProvider importu için componentimizin client side render olması gerekiyor. Bu yüzden “use client” ibaresini unutmayalım.
"use client"
import { ReactNode } from "react"
import { SessionProvider } from "next-auth/react"
interface ProviderProps {
children: ReactNode
}
const Provider: React.FC<ProviderProps> = ({ children }) => {
return <SessionProvider>{children}</SessionProvider>
}
export default Provider
Provider’ımızı oluşturup export ettikten sonra app klasörü altındaki layout’umuzda kullanıyoruz.
import Provider from "@/components/provider"
import "./globals.css"
import type { Metadata } from "next"
import { Inter } from "next/font/google"
const inter = Inter({ subsets: ["latin"] })
export const metadata: Metadata = {
title: "Next Auth Example",
description: "developed by kursat simsek",
}
export default function RootLayout({
children,
}: {
children: React.ReactNode
}) {
return (
<html lang="en">
<body className={inter.className}>
<Provider>{children}</Provider>
</body>
</html>
)
}
Tasarım & Kullanım
Şimdi ise sayfamız için bir tasarım oluşturalım. Ben daha düzenli bir kod yapısı için containers klasörü kullanıyorum. Anasayfamızda render etmek için containers klasörü içinde HomeContainer isimli component oluşturalım:
containers/home-container/index.tsx
Component’imiz şu şekilde olacak.
import LoginArea from "@/components/login"
function HomeContainer() {
return (
<div className="h-screen p-10">
<div className="text-center text-4xl font-bold">Hello !</div>
<LoginArea />
</div>
)
}
export default HomeContainer
Gördüğünüz gibi components klasörümden LoginArea’yı import edip burada render ediyorum. LoginArea component’ine geçmeden önce HomeContainer’ımızı app klasörünün altındaki page.tsx dosyamızda return etmeyi unutmayalım.
app/page.tsx
import HomeContainer from "@/containers/home-container"
export default function Home() {
return <HomeContainer />
}
Login işlemleri
Şimdi components klasörümüzün altında LoginArea component’imizi oluşturalım.
components/login/index.tsx
LoginArea component’imiz içinde öncelikle yapmamız gereken ise NextAuth.js’den signIn, signOut, useSession fonksiyonlarını import etmemiz. Bu arada bu importlarımızdan dolayı component’imiz yine client side render edilmeli bu yüzden “use client” ibaremizi sayfanın başına ekliyoruz.
"use client"
import { signIn, signOut, useSession } from "next-auth/react"
interface IUser {
name?: string | null | undefined
email?: string | null | undefined
image?: string | null | undefined
}
function LoginArea() {
const { data } = useSession()
const user: IUser | undefined = data?.user
return (
<div>
{user ? (
<div>
<div className="text-center text-5xl text-orange-400 font-bold mt-5">
{user.name}
</div>
<div className="flex align-center justify-center mt-5 ">
<img
className="w-64 rounded-full"
src={user.image ? user.image : undefined}
/>
</div>
<div className="text-center mt-10">
<button
className="bg-orange-400 w-2/6 h-10 rounded-lg text-white font-bold"
onClick={() => signOut()}
>
Sign Out
</button>
</div>
</div>
) : (
<div className="text-center mt-10">
<button
className="bg-orange-400 w-2/6 h-10 rounded-lg text-white font-bold"
onClick={() => signIn()}
>
Sign in
</button>
</div>
)}
</div>
)
}
export default LoginArea
LoginArea component’imizi bir kaç stil ekleyerek tamamlamış olduk. Burada dikkat etmemiz gereken şeyler useSession() hookunu kullanarak kullanıcı verilerine ulaşmak. Butonlara ise import ettiğimiz signIn() — signOut() fonksiyonlarını vermek.
Projemizi çalıştırdığımızda bizi şöyle bir ekran karşılayacaktır. 🙋🏻
Sign in butonuna tıkladığımızda ise bizi login ekranı karşılar. Burada artık Sign in with Google butonu vardır. Tıklayalım ve deneyelim 🤦
Fakat bir sorunla karşılaşacağız. 🫤
Erişim Engellendi Hatası | Authorized Redirect
Google bize burada 400 hata kodu dönerek OAuth 2.0 politikasına uymadığımız için erişimi engellediğini söylüyor.
Şimdi gerekli yetkileri vererek bu hatayı çözelim. Bunun için console.cloud.google.com/apis/credentials adresine gidiyoruz. Açılan sayfada OAuth 2.0 Client IDs kısmını bulalım.
Buradan Web application olanları sırasıyla düzenleyeceğiz. Tıklayalım ve düzenleme sayfasına girelim. Bizi Authorized JavaScript origins ve Authorized redirect URIs başlıkları karşılayacaktır. Eğer localde çalışıyorsanız Authorized JavaScript origins kısmına local base url’inizi eklemelisiniz. (Genellikle localhost:3000)
Authorized redirect URIs kısmına ise Google’ın bize döndüğü hatadaki redirect_uri’yi eklemeliyiz. Bunun için hata sayfasında hata ayrıntılarını inceleyin yazısına tıklayalım.
redirect_uri değerini kopyalayarak Authorized redirect URIs’e ekleyelim.
Son olarak ayarları kaydedelim ve projemize geri dönelim.
Tekrar Sign in with Google butonuna tıklayıp giriş yapmaya çalıştığımızda artık hata vermeyecektir. 🥳
Giriş yaptıktan sonra ise bizi anasayfa yönlendirip Google hesabımızın ismini ve fotoğrafını kullanarak karşılayacaktır.
Burada Sign Out butonuna tıkladığımızda da session’ımızı silip tekrar giriş yapmamızı isteyecektir.
Özet
Sonuç olarak bugün Next.js projemizde NextAuth.js kütüphanesini kullandık ve Google ayarlarını yaparak uygulamamıza Google ile giriş yapılmasını sağladık. Ben projede bir kaç değişiklik yapıp örneğini canlıya aldım. Projeyi veya örneği incelemek isterseniz aşağıya GitHub ve Vercel linklerini bırakıyorum. 🤗
Single & Albüm Tavsiye 🎉
Artık makalelerimin sonunda son zamanlarda dinlediğim ve kod yazarken dinlemesi keyifli olacağını düşündüğüm parçaları veya albümleri paylaşmaya karar verdim. Eğer kodun derinliklerine daldıysanız ve tam odaklanmışsanız aşağıdaki albümü kısık sesle dinlemeniz keyfinizi artıracaktır diye düşünüyorum ve çok çok keyifli — hatasız kodlamalar diliyorum. 👏