কম্পিউটার টিউটোরিয়াল

Auth.js এবং Upstash Redis ব্যবহার করে Next.js-এ নিরাপদ ব্যবহারকারী প্রমাণীকরণ

এই টিউটোরিয়ালে, আপনি Auth.js এবং Upstash Redis ব্যবহার করে একটি Next.js অ্যাপ্লিকেশনে ব্যবহারকারীর প্রমাণীকরণ বাস্তবায়ন করতে শিখবেন। আপনি কীভাবে প্রয়োজনীয় পরিবেশ সেট আপ করবেন, নিরাপদ ব্যবহারকারী সাইন-ইন এবং সাইন-আপের জন্য কাস্টম প্রমাণীকরণ প্রদানকারী তৈরি করবেন এবং সেশন পরিচালনার জন্য ডাটাবেস হিসাবে Upstash Redis সংহত করবেন তা শিখবেন।

পূর্বশর্ত

আপনার নিম্নলিখিতগুলির প্রয়োজন হবে:

  • Node.js 18 বা তার পরে
  • একটি Upstash অ্যাকাউন্ট

টেক স্ট্যাক

প্রযুক্তি বিবরণ Next.jsWeb.UpstashServerless ডাটাবেস প্ল্যাটফর্মের জন্য প্রতিক্রিয়া ফ্রেমওয়ার্ক। আপনি সেশন এবং ব্যবহারকারীর তথ্য পরিচালনার জন্য Upstash Redis ব্যবহার করতে যাচ্ছেন।

একটি Upstash Redis দৃষ্টান্ত সেট আপ করুন

আপনার Upstash ড্যাশবোর্ডে, Redis-এ যান ট্যাব করুন এবং একটি ডাটাবেস তৈরি করুন।

Auth.js এবং Upstash Redis ব্যবহার করে Next.js-এ নিরাপদ ব্যবহারকারী প্রমাণীকরণ

আপনি REST API বিভাগটি না পাওয়া পর্যন্ত নিচে স্ক্রোল করুন এবং .env নির্বাচন করুন বোতাম বিষয়বস্তু অনুলিপি করুন এবং এটি নিরাপদ কোথাও সংরক্ষণ করুন৷

Auth.js এবং Upstash Redis ব্যবহার করে Next.js-এ নিরাপদ ব্যবহারকারী প্রমাণীকরণ

একটি নতুন Next.js অ্যাপ্লিকেশন তৈরি করুন

একটি নতুন Next.js প্রকল্প তৈরি করে শুরু করা যাক। আপনার টার্মিনাল খুলুন এবং নিম্নলিখিত কমান্ডটি চালান:

npx create-next-app@latest my-app

যখন অনুরোধ করা হয়, নির্বাচন করুন:

  • Yes যখন TypeScript ব্যবহার করতে বলা হয়।
  • No যখন ESLint ব্যবহার করতে বলা হয়।
  • Yes যখন Tailwind CSS ব্যবহার করার জন্য অনুরোধ করা হয়।
  • No যখন src/ ব্যবহার করতে বলা হয় ডিরেক্টরি।
  • Yes যখন অ্যাপ রাউটার ব্যবহার করতে বলা হয়।
  • No যখন টার্বোপ্যাক ব্যবহার করতে বলা হয়।
  • No যখন ডিফল্ট আমদানি উপনাম (@/*) কাস্টমাইজ করার জন্য অনুরোধ করা হয় )।

এটি হয়ে গেলে, প্রজেক্ট ডিরেক্টরিতে যান এবং নিম্নলিখিত কমান্ডটি চালানোর মাধ্যমে অ্যাপটিকে ডেভেলপমেন্ট মোডে শুরু করুন:

cd my-app
npm run dev

অ্যাপটি লোকালহোস্টে চলতে হবে:3000। নিম্নলিখিত কমান্ডগুলির সাথে প্রয়োজনীয় নির্ভরতা ইনস্টল করতে ডেভেলপমেন্ট সার্ভার বন্ধ করুন:

npm install @upstash/redis nanoid
npm install next-auth @auth/core @auth/upstash-redis-adapter

ইনস্টল করা লাইব্রেরিগুলির মধ্যে রয়েছে:

  • nanoid :অনন্য, সুরক্ষিত আইডি তৈরি করার জন্য একটি লাইব্রেরি।
  • next-auth :Next.js.
  • -এর জন্য নির্মিত প্রমাণীকরণ সমাধান
  • @auth/core :Auth.js এ প্রমাণীকরণ পরিচালনার জন্য মূল প্যাকেজ।
  • @upstash/redis :SDK HTTP অনুরোধের মাধ্যমে Upstash Redis-এর সাথে ইন্টারঅ্যাক্ট করতে।
  • @auth/upstash-redis-adapter :Upstash Redis-এর সাথে Auth.js একীভূত করার জন্য অ্যাডাপ্টার।

এখন, একটি .env তৈরি করুন আপনার প্রকল্পের মূলে ফাইল করুন। আপনি AUTH_SECRET ব্যবহার করতে যাচ্ছেন , UPSTASH_REDIS_REST_URL এবং UPSTASH_REDIS_REST_TOKEN মান।

.env ফাইলে নিম্নলিখিত থাকা উচিত:

# .env
 
# Auth.js Environment Variable
AUTH_SECRET="..."
 
# Upstash Redis Environment Variables
UPSTASH_REDIS_REST_URL="https://...upstash.io"
UPSTASH_REDIS_REST_TOKEN="..."

Upstash Redis ক্লায়েন্টকে ইনস্ট্যান্টিয়েট করুন

redis.ts নামে একটি ফাইল তৈরি করুন lib-এ নিম্নলিখিত কোড সহ ডিরেক্টরি:

// File: lib/redis.ts
 
import { Redis } from '@upstash/redis'
 
export default new Redis({
 url: process.env.UPSTASH_REDIS_REST_URL,
 token: process.env.UPSTASH_REDIS_REST_TOKEN,
})

উপরের কোডে, একটি এজ-সামঞ্জস্যপূর্ণ রেডিস ক্লায়েন্ট ইন্সট্যান্স সমগ্র অ্যাপ্লিকেশন জুড়ে ব্যবহার করার জন্য রপ্তানি করা হয়৷

ব্যবহারকারীর ধরন এবং শংসাপত্র সাহায্যকারী সেট আপ করুন

types.ts নামে একটি ফাইল তৈরি করুন lib-এ নিম্নলিখিত কোড সহ ডিরেক্টরি:

// File: lib/types.ts
 
export interface UserType {
 id?: string
 email: string
 name?: string
 image?: string
 password?: string
 emailVerified?: string
}

UserType ইন্টারফেস অ্যাপ্লিকেশনে একটি ব্যবহারকারী বস্তুর গঠন সংজ্ঞায়িত করে। এতে রয়েছে:

  • id (ঐচ্ছিক):ব্যবহারকারীর জন্য একটি অনন্য শনাক্তকারী।
  • email (প্রয়োজনীয়):ব্যবহারকারীর ইমেল ঠিকানা।
  • name (ঐচ্ছিক):ব্যবহারকারীর নাম।
  • image (ঐচ্ছিক):ব্যবহারকারীর প্রোফাইল চিত্রের একটি URL বা পথ।
  • password (ঐচ্ছিক):ব্যবহারকারীর হ্যাশ করা পাসওয়ার্ড।
  • emailVerified (ঐচ্ছিক):একটি টাইমস্ট্যাম্প বা স্ট্রিং নির্দেশ করে যে/যখন ব্যবহারকারীর ইমেল যাচাই করা হয়েছে।

এই ইন্টারফেসটি সমগ্র অ্যাপ্লিকেশন জুড়ে ব্যবহারকারীর ডেটার জন্য একটি প্রকার সংজ্ঞা হিসাবে কাজ করে৷

আরও, credentials.ts নামে একটি ফাইল তৈরি করুন lib-এ নিম্নলিখিত কোড সহ ডিরেক্টরি:

// File: lib/credentials.ts
 
export function generateRandomToken() {
 const array = new Uint8Array(20)
 crypto.getRandomValues(array)
 return Array.from(array, (byte) => byte.toString(16).padStart(2, '0')).join('')
}
 
export function generateRandomString(inputValue: string) {
 const encoder = new TextEncoder()
 const data = encoder.encode(inputValue)
 return crypto.subtle.digest('SHA-256', data).then((hashBuffer) => {
 return Array.from(new Uint8Array(hashBuffer))
 .map((byte) => byte.toString(16).padStart(2, '0'))
 .join('')
 })
}
 
export async function hashPassword(password: string) {
 const encoder = new TextEncoder()
 const data = encoder.encode(password)
 const hashBuffer = await crypto.subtle.digest('SHA-256', data)
 return Array.from(new Uint8Array(hashBuffer))
 .map((byte) => byte.toString(16).padStart(2, '0'))
 .join('')
}
 
export async function comparePassword(password: string, hash: string) {
 const hashedPassword = await hashPassword(password)
 return hashedPassword === hash
}

উপরের কোডে, নিরাপদ টোকেন এবং হ্যাশ করা পাসওয়ার্ড তৈরি এবং পরিচালনার জন্য এজ-সামঞ্জস্যপূর্ণ ইউটিলিটি ফাংশনগুলি সংজ্ঞায়িত করা হয়েছে:

  • generateRandomToken :একটি 20-বাইট র্যান্ডম অ্যারে তৈরি করে এবং এটিকে হেক্সাডেসিমেল স্ট্রিংয়ে রূপান্তর করে একটি ক্রিপ্টোগ্রাফিকভাবে সুরক্ষিত র্যান্ডম টোকেন তৈরি করে৷
  • generateRandomString :একটি ইনপুট স্ট্রিং গ্রহণ করে, এটিকে বাইটে এনকোড করে, SHA-256 ব্যবহার করে হ্যাশ করে এবং একটি হেক্সাডেসিমাল স্ট্রিং হিসাবে হ্যাশ ফেরত দেয়। ইনপুট মান থেকে প্রাপ্ত সামঞ্জস্যপূর্ণ, অনন্য স্ট্রিং তৈরি করার জন্য দরকারী।
  • hashPassword :SHA-256 ব্যবহার করে একটি প্লেইনটেক্সট পাসওয়ার্ড হ্যাশ করে এবং ফলস্বরূপ হ্যাশকে হেক্সাডেসিমেল স্ট্রিংয়ে রূপান্তর করে। এটি নিরাপদে পাসওয়ার্ড সংরক্ষণের জন্য ব্যবহৃত হয়।
  • comparePassword :একটি প্লেইন টেক্সট পাসওয়ার্ডকে একটি হ্যাশ করা পাসওয়ার্ডের সাথে তুলনা করে ইনপুট হ্যাশ করে এবং এটি সঞ্চিত হ্যাশের সাথে মেলে কিনা তা পরীক্ষা করে৷

Auth.js এর সাথে Upstash Redis অ্যাডাপ্টার ব্যবহার করা

auth.ts নামে একটি ফাইল তৈরি করুন lib-এ নিম্নলিখিত কোড সহ ডিরেক্টরি:

// File: lib/auth.ts
 
import { UpstashRedisAdapter } from '@auth/upstash-redis-adapter'
import NextAuth from 'next-auth'
import providers from './providers'
import redis from './redis'
 
export const { handlers, signIn, signOut, auth } = NextAuth(() => ({
 providers,
 session: { strategy: 'jwt' },
 adapter: UpstashRedisAdapter(redis),
}))

উপরের কোডে, handlers তৈরির মাধ্যমে প্রমাণীকরণ সেট আপ করা হচ্ছে , signIn , signOut , এবং auth একটি কাস্টম কনফিগারেশন ব্যবহার করে ফাংশন। এটি একটি JWT-ভিত্তিক সেশন কৌশল ব্যবহার করে, UpstashRedisAdapter ব্যবহারকারীর ডেটা সংরক্ষণের জন্য একটি Upstash Redis ডাটাবেসের সাথে সংযোগ করতে, এবং providers-এ সংজ্ঞায়িত প্রমাণীকরণ প্রদানকারীদের একটি অ্যারে মডিউল এই সেটআপটি ব্যাকএন্ড হিসাবে Upstash Redis-এর সাথে প্রমাণীকরণ এবং সেশন পরিচালনার নির্বিঘ্ন একীকরণ সক্ষম করে৷

Aut.js এর সাথে কাস্টম প্রমাণীকরণ প্রদানকারী সেট আপ করুন

providers.ts নামে একটি ফাইল তৈরি করুন lib-এ নিম্নলিখিত কোড সহ ডিরেক্টরি:

// File: lib/providers.ts
 
import { nanoid } from 'nanoid'
import Credentials from 'next-auth/providers/credentials'
import { comparePassword, generateRandomString, hashPassword } from './credentials'
import redis from './redis'
import { UserType } from './types'
 
export default [
 Credentials({
 credentials: {
 email: {},
 password: {},
 },
 authorize: async (credentials, request) => {
 let type
 try {
 const tmp = new URL(request.url).searchParams.get('kind')
 if (tmp && typeof tmp === 'string') type = tmp
 } catch (e) {}
 if (!type || !credentials.email || typeof credentials.email !== 'string' || !credentials.password || typeof credentials.password !== 'string') return null
 const randomizedPassword = await generateRandomString(credentials.password)
 const userByEmail = await redis.get<string | null | undefined>(`user:email:${credentials.email}`)
 if (userByEmail) {
 if (type !== 'in') {
 console.log(`can not sign in in a non sign-in mode.`)
 throw new Error(`can not sign in in a non sign-in mode.`)
 }
 const user = await redis.get<UserType>(`user:${userByEmail}`)
 if (!user) {
 console.log(`Found the user by email from user:email:${userByEmail}, but the user object is missing at user:${userByEmail}`)
 return null
 }
 if (user.password) {
 const hashedPassword = await hashPassword(randomizedPassword)
 const isPasswordCorrect = await comparePassword(user.password, hashedPassword)
 if (isPasswordCorrect) {
 const { password, ...rest } = user
 return rest
 }
 throw new Error(`incorrect password for credentials.`)
 }
 throw new Error(`you are using some other authentication method already, but not credentials.`)
 } else {
 if (type !== 'up') {
 console.log(`can not sign up in a non sign-up mode.`)
 throw new Error(`can not sign up in a non sign-up mode.`)
 }
 const newUser = {
 name: null,
 image: null,
 emailVerified: null,
 email: credentials.email,
 password: randomizedPassword,
 }
 const tmp = nanoid()
 await redis.set(`user:email:${credentials.email}`, tmp)
 await redis.set(`user:${tmp}`, newUser)
 return newUser
 }
 },
 }),
]

উপরের কোডে, কাস্টম, শংসাপত্র-ভিত্তিক প্রমাণীকরণ প্রদানকারীর একটি অ্যারে রপ্তানি করা হয়। শংসাপত্র প্রদানকারী সাইন-ইন এবং সাইন-আপ লজিক উভয়ই পরিচালনা করে:এটি ব্যবহারকারী Redis-এ বিদ্যমান কিনা তা পরীক্ষা করে এবং হয় তাদের পাসওয়ার্ড যাচাই করে বা একটি নতুন ব্যবহারকারী তৈরি করে। সাইন ইন করলে, এটি প্রদত্ত পাসওয়ার্ড (এলোমেলো স্ট্রিং ব্যবহার করে হ্যাশ করা) সংরক্ষিত পাসওয়ার্ডের সাথে তুলনা করে; সাইন আপ করলে, এটি Upstash Redis-এ একটি নতুন ব্যবহারকারী এন্ট্রি তৈরি করে। কোডটি ব্যবহারকারীর ডেটা স্টোরেজের জন্য Upstash Redis ব্যবহার করে এবং নিশ্চিত করে যে প্রক্রিয়াটি হয় সাইন-আপ বা সাইন-ইন মোডে করা হয়েছে URL-এর ধরনের প্যারামিটারের উপর ভিত্তি করে৷

Authentication API রুট সেট আপ করুন (Auth.js দ্বারা চালিত)

route.ts নামে একটি ফাইল তৈরি করুন app/api/auth/[...nextauth]-এ নিম্নলিখিত কোড সহ ডিরেক্টরি:

// File: app/api/auth/[...nextauth]/route.ts
 
export const runtime = 'edge'
 
import { handlers } from '@/lib/auth'
 
export const { GET, POST } = handlers

উপরের কোডে, দুটি এন্ডপয়েন্ট হ্যান্ডলার GET এবং POST রপ্তানি করা হয় যেগুলি handlers দ্বারা পরিচালিত হয় @/lib/auth.ts থেকে ফাংশন এক্সপোর্ট করা হয়েছে ফাইল।

route.ts নামে একটি ফাইল তৈরি করুন app/api/refresh-এ নিম্নলিখিত কোড সহ ডিরেক্টরি:

// File: app/api/refresh/route.ts
 
export const runtime = 'edge'
 
export const dynamic = 'force-dynamic'
 
export const fetchCache = 'force-no-store'
 
import { auth } from '@/lib/auth'
import redis from '@/lib/redis'
import { UserType } from '@/lib/types'
import { encode } from '@auth/core/jwt'
import { cookies } from 'next/headers'
import { NextResponse } from 'next/server'
 
export async function GET(request: Request) {
 const useSecureCookie = request.url.startsWith('https:')
 const salt = useSecureCookie ? '__Secure-authjs.session-token' : 'authjs.session-token'
 if (!process.env.AUTH_SECRET) return new NextResponse(null, { status: 500 })
 const [session, cookieStore] = await Promise.all([auth(), cookies()])
 if (!session?.user?.email) return new NextResponse(null, { status: 400 })
 const userByEmail = await redis.get(`user:email:${session.user.email}`)
 const userData = await redis.get<UserType>(`user:${userByEmail}`)
 if (!userData?.email) cookieStore.set(salt, toString(), { secure: useSecureCookie, path: '/', httpOnly: true, sameSite: 'lax', maxAge: 0 })
 else {
 const { image, password, ...rest } = userData
 const saltVal = await encode({ salt, secret: process.env.AUTH_SECRET, token: { ...rest, picture: image } })
 cookieStore.set(salt, saltVal, { secure: useSecureCookie, path: '/', httpOnly: true, sameSite: 'lax' })
 }
 return new NextResponse()
}

উপরের কোডে, ব্যবহারকারীর সেশন রিফ্রেশ করার জন্য একটি এজ-সামঞ্জস্যপূর্ণ API রুট তৈরি করা হচ্ছে। এটি Redis থেকে ব্যবহারকারীর সেশন এবং সম্পর্কিত ডেটা নিয়ে আসে, ব্যবহারকারীর ইমেল যাচাই করে এবং সেশন কুকি আপডেট করে। যদি ব্যবহারকারীর ডেটা অবৈধ বা অনুপস্থিত হয়, সেশন কুকি সাফ করা হয়; অন্যথায়, একটি নতুন স্বাক্ষরিত টোকেন তৈরি করা হয় এবং কুকিতে সংরক্ষণ করা হয়।

route.ts নামে একটি ফাইল তৈরি করুন app/api/user-এ নিম্নলিখিত কোড সহ ডিরেক্টরি:

// File: app/api/user/route.ts
 
export const runtime = 'edge'
 
export const dynamic = 'force-dynamic'
 
export const fetchCache = 'force-no-store'
 
import { auth } from '@/lib/auth'
import redis from '@/lib/redis'
import { UserType } from '@/lib/types'
import { NextResponse } from 'next/server'
 
export async function POST(request: Request) {
 try {
 const session = await auth()
 if (!session?.user?.email) return new NextResponse(null, { status: 400 })
 const body = await request.json()
 const userByEmail = await redis.get(`user:email:${session.user.email}`)
 const userData = await redis.get<UserType>(`user:${userByEmail}`)
 if (!userData) return new NextResponse(null, { status: 404 })
 if (body.name) userData.name = body.name
 if (body.image) userData.image = body.image
 await redis.set(`user:${userByEmail}`, userData)
 return new NextResponse()
 } catch (e: any) {
 const message = e.message || e.toString()
 console.log(message)
 return new NextResponse(message, { status: 500 })
 }
}

উপরের কোডে, ব্যবহারকারীর ডেটা আপডেট করার জন্য একটি এজ-সামঞ্জস্যপূর্ণ API রুট তৈরি করা হচ্ছে। এটি ব্যবহারকারীকে প্রমাণীকরণ করে, তাদের ইমেল ব্যবহার করে Redis থেকে তাদের ডেটা আনে এবং অনুরোধের অংশের উপর ভিত্তি করে তাদের তথ্য (যেমন, নাম বা ছবি) আপডেট করে। যদি ব্যবহারকারী খুঁজে না পাওয়া যায় বা একটি ত্রুটি ঘটে, উপযুক্ত স্ট্যাটাস কোড এবং প্রতিক্রিয়া ফেরত দেওয়া হয়।

Aut.js এর সাথে Next.js Middleware সেট আপ করুন

middleware.ts নামে একটি ফাইল তৈরি করুন নিম্নলিখিত কোড সহ আপনার প্রকল্পের রুট ডিরেক্টরিতে:

// File: middleware.ts
 
export { auth as middleware } from '@/lib/auth'
 
export const config = {
 matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
}

উপরের কোডে, auth পুনরায় রপ্তানি করে মিডলওয়্যার তৈরি করা হয়েছে @/lib/auth থেকে ফাংশন মডিউল মিডলওয়্যারটি API রুট, স্ট্যাটিক ফাইল, ইমেজ অ্যাসেট এবং ফ্যাভিকন ছাড়া সমস্ত রুটে প্রমাণীকরণ প্রয়োগ করে, যেমনটি matcher দ্বারা নির্দিষ্ট করা হয়েছে। কনফিগারেশন এটি নিশ্চিত করে যে অ-বাদ দেওয়া রুটগুলি Auth.js এর সাথে সেট করা প্রমাণীকরণ যুক্তি দ্বারা সুরক্ষিত।

Next.js অ্যাপ রাউটার উপাদানগুলিতে Auth.js ব্যবহার করুন

NextAuthProvider.tsx নামে একটি ফাইল তৈরি করুন app-এ নিম্নলিখিত কোড সহ ডিরেক্টরি:

// File: app/NextAuthProvider.tsx
 
'use client'
 
import { SessionProvider } from 'next-auth/react'
 
type Props = {
 children?: React.ReactNode
}
 
export default function ({ children }: Props) {
 return <SessionProvider>{children}</SessionProvider>
}

উপরের কোডে, NextAuth-এর SessionProvider দিয়ে অ্যাপ্লিকেশনটি মোড়ানোর জন্য একটি ক্লায়েন্ট-সাইড প্রতিক্রিয়া উপাদান তৈরি করা হয়েছে . উপাদান children গ্রহণ করে প্রপস হিসাবে এবং নিশ্চিত করে যে মোড়ানো উপাদানগুলি NextAuth দ্বারা প্রদত্ত ব্যবহারকারীর সেশন প্রসঙ্গে অ্যাক্সেস রয়েছে। এই সেটআপটি Next.js.

-এ অ্যাপ্লিকেশন জুড়ে প্রমাণীকরণ অবস্থা পরিচালনার জন্য অপরিহার্য

csrf.tsx নামে একটি ফাইল তৈরি করুন app-এ নিম্নলিখিত কোড সহ ডিরেক্টরি:

// File: app/csrf.tsx
 
'use client'
 
import { getCsrfToken } from 'next-auth/react'
import { useEffect, useState } from 'react'
 
export function CSRFInput() {
 const [csrfToken, setCsrfToken] = useState<string>()
 useEffect(() => {
 getCsrfToken().then((res) => setCsrfToken(res))
 }, [])
 return <input type="hidden" name="csrfToken" defaultValue={csrfToken} />
}

উপরের কোডে, একটি ক্লায়েন্ট-সাইড রিঅ্যাক্ট কম্পোনেন্ট এক্সপোর্ট করা হয়েছে যা NextAuth-এর getCsrfToken ব্যবহার করে একটি CSRF টোকেন নিয়ে আসে। ফাংশন এবং এটি একটি স্টেট ভেরিয়েবলে সঞ্চয় করে। উপাদানটি CSRF টোকেন ধারণকারী একটি লুকানো ইনপুট ক্ষেত্র রেন্ডার করে, টোকেনটিকে একটি লুকানো মান হিসাবে অন্তর্ভুক্ত করে সুরক্ষিত ফর্ম জমা দেওয়ার অনুমতি দেয়। এটি ক্রস-সাইট অনুরোধ জালিয়াতি আক্রমণ থেকে রক্ষা করার জন্য দরকারী৷

provider.tsx নামে একটি ফাইল তৈরি করুন app-এ নিম্নলিখিত কোড সহ ডিরেক্টরি:

// File: app/provider.tsx
 
'use client'
 
import { Button } from '@/components/ui/button'
import { Icon } from '@iconify/react'
import { signIn } from 'next-auth/react'
 
export default function ({ provider, prefix }: { prefix: string; provider: { name: string; id: string } }) {
 return (
 <Button onClick={() => signIn(provider.id)} key={provider.name} variant="outline" className="flex w-full gap-x-3">
 {provider.id === 'google' && <Icon fontSize={18} icon="flat-color-icons:google" />}
 <span className="text-black">
 {prefix} with {provider.name}
 </span>
 </Button>
 )
}

উপরের কোডে, বিভিন্ন প্রমাণীকরণ প্রদানকারীদের জন্য একটি কাস্টমাইজযোগ্য সাইন-ইন বোতাম রেন্ডার করার জন্য একটি প্রতিক্রিয়া উপাদান রপ্তানি করা হয়। এটি provider গ্রহণ করে (name ধারণকারী এবং id ) এবং prefix প্রপস হিসাবে বোতামটি signIn ট্রিগার করে নির্দিষ্ট প্রদানকারীর জন্য ফাংশন এবং গতিশীলভাবে প্রদানকারীর id এর উপর ভিত্তি করে একটি আইকন এবং লেবেল প্রদর্শন করে .

layout.tsx নামের ফাইলটি আপডেট করুন app-এ নিম্নলিখিত কোড সহ ডিরেক্টরি:

// File: app/layout.tsx
 
import './globals.css'
import NextAuthProvider from './NextAuthProvider'
 
export default function ({
 children,
}: Readonly<{
 children: React.ReactNode
}>) {
 return (
 <html lang="en">
 <body className="bg-white text-black antialiased">
 <NextAuthProvider>
 <div className="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 flex flex-col">{children}</div>
 </NextAuthProvider>
 </body>
 </html>
 )
}

উপরের কোডে, Next.js লেআউট সমগ্র পৃষ্ঠাটিকে গ্লোবাল স্টাইল এবং প্রমাণীকরণ প্রসঙ্গে মোড়ানো হচ্ছে। এটি globals.css আমদানি করে গ্লোবাল স্টাইলিং এবং NextAuthProvider এর জন্য প্রমাণীকরণ অবস্থা পরিচালনা করতে। children প্রপ নেস্টেড পৃষ্ঠার বিষয়বস্তুকে প্রতিনিধিত্ব করে, যা প্রতিক্রিয়াশীল প্যাডিং এবং সর্বাধিক প্রস্থ সহ একটি স্টাইলযুক্ত পাত্রে মোড়ানো থাকে, যা সমস্ত পৃষ্ঠাগুলির জন্য একটি সামঞ্জস্যপূর্ণ বিন্যাস প্রদান করে৷

ক্লায়েন্ট-সাইড পৃষ্ঠায় ব্যবহারকারীর প্রমাণীকরণ অবস্থা লোড করুন

page.tsx নামের ফাইলটি আপডেট করুন app-এ নিম্নলিখিত কোড সহ ডিরেক্টরি:

// File: app/page.tsx
 
'use client'
 
import { signOut, useSession } from 'next-auth/react'
 
export default function () {
 const { data, status } = useSession()
 return (
 <>
 {JSON.stringify({ data, status })}
 <button onClick={() => signOut()}>Sign Out</button>
 </>
 )
}

উপরের কোডে, একটি ক্লায়েন্ট-সাইড প্রতিক্রিয়া উপাদান যা ব্যবহারকারীর সেশন ডেটা প্রদর্শন করে এবং একটি "সাইন আউট" বোতাম সরবরাহ করে তা রপ্তানি হয়৷ এটি NextAuth এর useSession ব্যবহার করে সেশন ডেটা এবং স্থিতি পুনরুদ্ধার করার জন্য হুক, একটি JSON স্ট্রিং হিসাবে প্রদর্শন করে। signOut যখন বোতামটি ক্লিক করা হয় তখন ফাংশন বলা হয়, ব্যবহারকারীকে লগ আউট করার অনুমতি দেয়।

একটি গতিশীল সাইন-ইন পৃষ্ঠা তৈরি করুন (Aut.js ব্যবহার করে)

page.tsx নামে একটি ফাইল তৈরি করুন app/signin-এ নিম্নলিখিত কোড সহ ডিরেক্টরি:

// File: app/signin/page.tsx
 
export const runtime = 'edge'
 
import { CSRFInput } from '@/app/csrf'
import Provider from '@/app/provider'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { auth } from '@/lib/auth'
import providers from '@/lib/providers'
import { unstable_noStore } from 'next/cache'
import Link from 'next/link'
import { redirect } from 'next/navigation'
 
export default async function () {
 unstable_noStore()
 const session = await auth()
 if (session) redirect('/')
 return (
 <div className="border md:border-white/10 flex items-center justify-center py-12">
 <div className="mx-auto grid w-[350px] gap-6">
 <div className="grid gap-2 text-center">
 <h1 className="text-3xl font-bold">Sign In</h1>
 <p className="text-balance text-muted-foreground">Enter your email below to sign in to your account</p>
 </div>
 {providers
 .filter((provider) => (typeof provider === 'function' ? provider({}).id : provider.id) !== 'credentials')
 .map((provider) => (
 <Provider
 prefix="Sign in"
 key={typeof provider === 'function' ? provider({}).name : provider.name}
 provider={typeof provider === 'function' ? provider({}) : provider}
 />
 ))}
 <p className="text-gray-300 text-xs text-center">OR</p>
 <form method="POST" className="grid gap-4" action="/api/auth/callback/credentials?kind=in">
 <div className="grid gap-2">
 <Label htmlFor="email">Email</Label>
 <Input name="email" id="email" type="email" placeholder="m@example.com" required />
 </div>
 <div className="grid gap-2">
 <Label htmlFor="password">Password</Label>
 <Input name="password" id="password" type="password" required />
 <CSRFInput />
 </div>
 <Button type="submit" className="w-full">
 Sign In
 </Button>
 </form>
 <div className="mt-4 text-center text-sm">
 Don&apos;t have an account?{' '}
 <Link href="/signup" className="underline">
 Sign up
 </Link>
 </div>
 </div>
 </div>
 )
}

উপরের কোডে, একটি সাইন-ইন পৃষ্ঠা তৈরি করা হচ্ছে। এটি একটি ব্যবহারকারীর সেশন ইতিমধ্যে বিদ্যমান কিনা তা পরীক্ষা করে; যদি তাই হয়, এটি হোমপেজে পুনঃনির্দেশিত করে। পৃষ্ঠাটি একটি সাইন-ইন ফর্ম প্রদর্শন করে যেখানে ব্যবহারকারীরা তাদের ইমেল এবং পাসওয়ার্ড লিখতে পারে, সাথে বিভিন্ন প্রদানকারী ব্যবহার করে সাইন ইন করার বিকল্পগুলিও। এতে নিরাপত্তার জন্য একটি CSRF টোকেন এবং নতুন ব্যবহারকারীদের জন্য সাইন-আপ পৃষ্ঠার একটি লিঙ্কও রয়েছে৷

একটি গতিশীল সাইন-আপ পৃষ্ঠা তৈরি করুন (Aut.js ব্যবহার করে)

page.tsx নামে একটি ফাইল তৈরি করুন app/signup-এ নিম্নলিখিত কোড সহ ডিরেক্টরি:

// File: app/signup/page.tsx
 
export const runtime = 'edge'
 
import { CSRFInput } from '@/app/csrf'
import Provider from '@/app/provider'
import { Button } from '@/components/ui/button'
import { Input } from '@/components/ui/input'
import { Label } from '@/components/ui/label'
import { auth } from '@/lib/auth'
import providers from '@/lib/providers'
import { unstable_noStore } from 'next/cache'
import Link from 'next/link'
import { redirect } from 'next/navigation'
 
export default async function () {
 unstable_noStore()
 const session = await auth()
 if (session) redirect('/')
 return (
 <div className="border md:border-white/10 flex items-center justify-center py-12">
 <div className="mx-auto grid w-[350px] gap-6">
 <div className="grid gap-2 text-center">
 <h1 className="text-3xl font-bold">Sign Up</h1>
 <p className="text-balance text-muted-foreground">Enter your email below to sign up with an account</p>
 </div>
 {providers
 .filter((provider) => (typeof provider === 'function' ? provider({}).id : provider.id) !== 'credentials')
 .map((provider) => (
 <Provider
 prefix="Sign up"
 key={typeof provider === 'function' ? provider({}).name : provider.name}
 provider={typeof provider === 'function' ? provider({}) : provider}
 />
 ))}
 <p className="text-gray-300 text-xs text-center">OR</p>
 <form method="POST" className="grid gap-4" action="/api/auth/callback/credentials?kind=up">
 <div className="grid gap-2">
 <Label htmlFor="email">Email</Label>
 <Input name="email" id="email" type="email" placeholder="m@example.com" required />
 </div>
 <div className="grid gap-2">
 <div className="flex items-center">
 <Label htmlFor="password">Password</Label>
 </div>
 <Input name="password" id="password" type="password" required />
 <CSRFInput />
 </div>
 <Button type="submit" className="w-full">
 Sign Up
 </Button>
 </form>
 <div className="mt-4 text-center text-sm">
 Don&apos;t have an account?{' '}
 <Link href="/signin" className="underline">
 Sign In
 </Link>
 </div>
 </div>
 </div>
 )
}

উপরের কোডে, একটি সাইন আপ পেজ তৈরি করা হচ্ছে। এটি একটি ব্যবহারকারীর সেশন ইতিমধ্যে বিদ্যমান কিনা তা পরীক্ষা করে; যদি তাই হয়, এটি হোমপেজে পুনঃনির্দেশিত করে। পৃষ্ঠাটি একটি সাইন-আপ ফর্ম প্রদর্শন করে যেখানে ব্যবহারকারীরা তাদের ইমেল এবং পাসওয়ার্ড লিখতে পারে, সাথে বিভিন্ন প্রদানকারী ব্যবহার করে সাইন ইন করার বিকল্পগুলিও। এতে নিরাপত্তার জন্য একটি CSRF টোকেন এবং বিদ্যমান ব্যবহারকারীদের জন্য সাইন-ইন পৃষ্ঠার একটি লিঙ্কও রয়েছে৷

যে অনেক শেখার ছিল! আপনি এখন সব সম্পন্ন করেছেন ✨

রেফারেন্স

আরও বিশদ অন্তর্দৃষ্টির জন্য, এই ব্লগে উদ্ধৃত রেফারেন্সগুলি অন্বেষণ করুন৷

  • GitHub সংগ্রহস্থল
  • Auth.js - শংসাপত্র প্রমাণীকরণ
  • Auth.js - Upstash Redis Adapter
  • Next.js - কুকিজ

উপসংহার

এই টিউটোরিয়ালে, আপনি শিখেছেন কিভাবে Auth.js এবং Upstash Redis ব্যবহার করে একটি Next.js অ্যাপ্লিকেশনে ব্যবহারকারীর প্রমাণীকরণ বাস্তবায়ন করতে হয়। আপনি পরিবেশের ভেরিয়েবলের সেটআপ, একটি রেডিস ক্লায়েন্ট তৈরি এবং একটি কাস্টম প্রমাণীকরণ প্রদানকারীর বাস্তবায়ন শিখেছেন। উপরন্তু, আপনি ব্যবহারকারীর সাইন-ইন এবং সাইন-আপ প্রক্রিয়ার পাশাপাশি সেশন পরিচালনার জন্য Next.js-এ API রুট সেট আপ করতে শিখেছেন। এই পদক্ষেপগুলি অনুসরণ করে, আপনি Upstash Redis এর সাথে আপনার Next.js অ্যাপ্লিকেশনগুলিতে ব্যবহারকারীর প্রমাণীকরণ এবং ডেটা স্টোরেজ কার্যকরভাবে পরিচালনা করতে পারেন৷


  1. এইচটিএমএল ডম স্টাইল টেক্সট ডেকোরেশন প্রপার্টি

  2. OpenCV হাফ সার্কেল ট্রান্সফর্মের জাভা বাস্তবায়ন।

  3. রেডিস জেডআরইএম - রেডিসে সাজানো সেট মান থেকে কীভাবে একটি উপাদান মুছবেন

  4. Logger এবং Lograge সঙ্গে রুবি লগ ইন করুন