paint-brush
সর্বশেষ Next.js বৈশিষ্ট্য সহ Firebase প্রমাণীকরণ ব্যবহার করাদ্বারা@awinogrodzki
22,972 পড়া
22,972 পড়া

সর্বশেষ Next.js বৈশিষ্ট্য সহ Firebase প্রমাণীকরণ ব্যবহার করা

দ্বারা Amadeusz Winogrodzki32m2024/04/04
Read on Terminal Reader

অতিদীর্ঘ; পড়তে

শূন্য-বান্ডেল আকার `next-firebase-auth-edge` লাইব্রেরি ব্যবহার করে Next.js-এর সাথে Firebase প্রমাণীকরণকে একীভূত করার জন্য একটি ব্যাপক, ধাপে ধাপে নির্দেশিকা। এটি ব্যবহারকারীর নিবন্ধন, লগইন এবং লগআউট কার্যকারিতার জন্য পদক্ষেপগুলি অন্তর্ভুক্ত করে, সাথে একটি বিরামহীন ব্যবহারকারীর অভিজ্ঞতার জন্য পুনঃনির্দেশ লজিক সহ। এই নির্দেশিকাটিতে, আপনি শিখতে যাচ্ছেন কিভাবে ফায়ারবেস প্রমাণীকরণকে সর্বশেষ Next.js বৈশিষ্ট্যগুলির সাথে একীভূত করতে হয়, যেমন অ্যাপ রাউটার, মিডলওয়্যার এবং সার্ভার উপাদান। এটি Vercel-এ অ্যাপ স্থাপন করার নির্দেশনা দিয়ে শেষ হয়, লাইব্রেরির ব্যবহারের সহজলভ্যতা এবং ডেভেলপারদের জন্য ভবিষ্যতের-প্রমাণ নকশা প্রদর্শন করে যারা Firebase প্রমাণীকরণের সাথে তাদের Next.js অ্যাপ্লিকেশনগুলিকে উন্নত করতে চাইছে।
featured image - সর্বশেষ Next.js বৈশিষ্ট্য সহ Firebase প্রমাণীকরণ ব্যবহার করা
Amadeusz Winogrodzki HackerNoon profile picture
0-item
1-item

next-firebase-auth-edge এর ভূমিকা

আপনার বিদ্যমান বা নতুন Next.js অ্যাপ্লিকেশনে Firebase প্রমাণীকরণ যোগ করার উপায় অনুসন্ধান করার সময় আপনি সম্ভবত এই নিবন্ধটি পেয়েছেন। আপনি একটি স্মার্ট, নিরপেক্ষ এবং ভবিষ্যৎ-ভিত্তিক সিদ্ধান্ত নেওয়ার লক্ষ্য রাখেন যা আপনার অ্যাপের সফল হওয়ার সম্ভাবনাকে সর্বাধিক করে তুলবে। নেক্সট-ফায়ারবেস-অথ-এজ-এর স্রষ্টা হিসাবে, আমাকে অবশ্যই স্বীকার করতে হবে যে সম্পূর্ণ নিরপেক্ষ মতামত প্রদান করা আমার শক্তি নয়, তবে অন্তত আমি লাইব্রেরি ডিজাইন করার সময় যে পদ্ধতিটি নিয়েছিলাম তা সমর্থন করার চেষ্টা করব। আশা করি, এই নির্দেশিকাটির শেষে, আপনি দীর্ঘমেয়াদী জন্য সহজ এবং কার্যকর উভয় পদ্ধতি খুঁজে পেতে পারেন।


কিভাবে এটা শুরু

আমি আপনাকে দীর্ঘ ভূমিকা সংরক্ষণ করব. আমাকে শুধু বলতে দিন যে লাইব্রেরির ধারণাটি সম্ভবত আপনার অনুরূপ পরিস্থিতি দ্বারা অনুপ্রাণিত হয়েছিল। এটি সেই সময় ছিল যখন Next.js অ্যাপ রাউটারের একটি ক্যানারি সংস্করণ প্রকাশ করেছিল। আমি এমন অ্যাপে কাজ করছিলাম যা পুনঃলিখন এবং অভ্যন্তরীণ পুনঃনির্দেশের উপর ব্যাপকভাবে নির্ভর করে। এর জন্য, আমরা কাস্টম Node.js express সার্ভার রেন্ডারিং Next.js অ্যাপ ব্যবহার করছিলাম।


আমরা অ্যাপ রাউটার এবং সার্ভার উপাদানগুলির জন্য সত্যিই উত্তেজিত ছিলাম, তবুও সচেতন যে এটি আমাদের কাস্টম সার্ভারের সাথে সামঞ্জস্যপূর্ণ হবে না। মিডলওয়্যারকে শক্তিশালী বৈশিষ্ট্যের মতো মনে হয়েছিল যে আমরা একটি কাস্টম এক্সপ্রেস সার্ভারের প্রয়োজনীয়তা দূর করতে সুবিধা নিতে পারি, পরিবর্তে কেবলমাত্র Next.js-এর অন্তর্নির্মিত বৈশিষ্ট্যগুলির উপর নির্ভর করতে পছন্দ করি যাতে ব্যবহারকারীদের গতিশীলভাবে বিভিন্ন পৃষ্ঠায় পুনঃনির্দেশিত এবং পুনর্লিখন করা যায়।


সেই সময়, আমরা নেক্সট-ফায়ারবেস-উথ ব্যবহার করছিলাম। আমরা সত্যিই লাইব্রেরিটি পছন্দ করেছি, কিন্তু এটি next.config.js , pages/_app.tsx , pages/api/login.ts , pages/api/logout.ts ফাইলগুলির মাধ্যমে আমাদের প্রমাণীকরণের যুক্তি ছড়িয়ে দিয়েছে, যা উত্তরাধিকার হিসাবে বিবেচিত হতে চলেছে শীঘ্রই যথেষ্ট এছাড়াও, লাইব্রেরিটি মিডলওয়্যারের সাথে সামঞ্জস্যপূর্ণ ছিল না, যা আমাদের ইউআরএল পুনঃলিখন বা ব্যবহারকারীদের তাদের প্রসঙ্গের উপর ভিত্তি করে পুনঃনির্দেশ করতে বাধা দেয়।


তাই, আমি আমার অনুসন্ধান শুরু করেছি, কিন্তু আমার আশ্চর্য, আমি এমন কোনো লাইব্রেরি খুঁজে পাইনি যা মিডলওয়্যারের মধ্যে ফায়ারবেস প্রমাণীকরণ সমর্থন করে। - কেন এমন হতে পারে? এটা অসম্ভব! Node.js এবং React-এ 11 বছরেরও বেশি বাণিজ্যিক অভিজ্ঞতা সহ একজন সফ্টওয়্যার ইঞ্জিনিয়ার হিসাবে, আমি এই সমস্যা মোকাবেলা করার জন্য প্রস্তুত ছিলাম।


তাই, আমি শুরু. এবং উত্তর সুস্পষ্ট হয়ে ওঠে. মিডলওয়্যার এজ রানটাইমের ভিতরে চলছে। Edge Runtime-এর মধ্যে উপলব্ধ ওয়েব ক্রিপ্টো API-এর সাথে সামঞ্জস্যপূর্ণ কোনো ফায়ারবেস লাইব্রেরি নেই। আমি ধ্বংস হয়ে গিয়েছিলাম . আমি অসহায় বোধ করলাম। নতুন এবং অভিনব এপিআইগুলির সাথে খেলার জন্য এই প্রথম কি আমাকে সত্যিই অপেক্ষা করতে হবে? - না। একটি প্রেক্ষিত পাত্র boils না. আমি দ্রুত কান্নাকাটি বন্ধ করে দিলাম এবং রিভার্স-ইঞ্জিনিয়ার নেক্সট-ফায়ারবেস-অথ , ফায়ারবেস-অ্যাডমিন এবং আরও কয়েকটি JWT প্রমাণীকরণ লাইব্রেরি এজ রানটাইমের সাথে খাপ খাইয়ে নিতে শুরু করলাম। আমি পূর্ববর্তী প্রমাণীকরণ লাইব্রেরিগুলির সাথে যে সমস্ত সমস্যাগুলির সম্মুখীন হয়েছিলাম সেগুলি সমাধান করার সুযোগটি আমি ব্যবহার করেছি, যার লক্ষ্য হল সবচেয়ে হালকা, সহজে কনফিগার করা এবং ভবিষ্যত-ভিত্তিক প্রমাণীকরণ লাইব্রেরি তৈরি করা।


প্রায় দুই সপ্তাহ পরে, পরবর্তী-ফায়ারবেস-অথ-এজ- এর 0.0.1 সংস্করণের জন্ম হয়েছিল। এটি ধারণার একটি কঠিন প্রমাণ ছিল, কিন্তু আপনি সংস্করণ 0.0.1 ব্যবহার করতে চান না। আমাকে বিশ্বাস কর.


এটা কিভাবে যাচ্ছে

প্রায় দুই বছর পরে , আমি ঘোষণা করতে পেরে রোমাঞ্চিত যে 372 কমিট করার পরে, 110টি সমস্যার সমাধান করা হয়েছে , এবং বিশ্বব্যাপী দুর্দান্ত ডেভেলপারদের কাছ থেকে অমূল্য প্রতিক্রিয়ার বোটলোড , লাইব্রেরিটি এমন একটি পর্যায়ে পৌঁছেছে যেখানে আমার অন্য স্বয়ং অনুমোদনের জন্য আমার কাছে নোড হয়েছে৷



আমার অন্য স্বয়ং



এই নির্দেশিকায়, আমি স্ক্র্যাচ থেকে প্রমাণীকৃত Next.js অ্যাপ তৈরি করতে next-firebase-auth-edge- এর সংস্করণ 1.4.1 ব্যবহার করব। আমরা একটি নতুন ফায়ারবেস প্রজেক্ট এবং Next.js অ্যাপ তৈরি করে শুরু করে next-firebase-auth-edge এবং firebase/auth লাইব্রেরির সাথে একীভূতকরণের মাধ্যমে প্রতিটি ধাপে বিস্তারিতভাবে যাব। এই টিউটোরিয়ালের শেষে, সবকিছু স্থানীয়ভাবে এবং উৎপাদন-প্রস্তুত পরিবেশে কাজ করছে তা নিশ্চিত করতে আমরা অ্যাপটিকে Vercel-এ স্থাপন করব।


Firebase সেট আপ করা হচ্ছে

এই অংশটি ধরে নেয় যে আপনি এখনও Firebase প্রমাণীকরণ সেটআপ করেননি। অন্যথায় পরবর্তী অংশ এড়িয়ে যেতে দ্বিধা বোধ করুন.


চলুন ফায়ারবেস কনসোলে যান এবং একটি প্রকল্প তৈরি করুন


প্রজেক্ট তৈরি হওয়ার পর, ফায়ারবেস প্রমাণীকরণ সক্ষম করি। কনসোলটি খুলুন এবং বিল্ড> প্রমাণীকরণ> সাইন-ইন পদ্ধতি অনুসরণ করুন এবং ইমেল এবং পাসওয়ার্ড পদ্ধতি সক্ষম করুন। এটি সেই পদ্ধতি যা আমরা আমাদের অ্যাপে সমর্থন করতে যাচ্ছি


ইমেল/পাসওয়ার্ড সাইন-ইন পদ্ধতি সক্রিয় করা হচ্ছে


আপনি আপনার প্রথম সাইন-ইন পদ্ধতি সক্ষম করার পরে, আপনার প্রকল্পের জন্য Firebase প্রমাণীকরণ সক্ষম করা উচিত এবং আপনি প্রকল্প সেটিংসে আপনার ওয়েব API কী পুনরুদ্ধার করতে পারেন


ওয়েব API কী পুনরুদ্ধার করুন


API কী অনুলিপি করুন এবং এটি নিরাপদ রাখুন। এখন, পরবর্তী ট্যাব খুলুন - ক্লাউড মেসেজিং, এবং প্রেরক আইডি নোট করুন। আমরা পরে এটা প্রয়োজন যাচ্ছি.


প্রেরক আইডি পুনরুদ্ধার করুন


শেষ কিন্তু অন্তত নয়, আমাদের পরিষেবা অ্যাকাউন্টের শংসাপত্র তৈরি করতে হবে। এগুলি আপনার অ্যাপকে আপনার ফায়ারবেস পরিষেবাগুলিতে সম্পূর্ণ অ্যাক্সেস পাওয়ার অনুমতি দেবে৷ প্রকল্প সেটিংস > পরিষেবা অ্যাকাউন্টে যান এবং নতুন ব্যক্তিগত কী তৈরি করুন ক্লিক করুন। এটি পরিষেবা অ্যাকাউন্টের শংসাপত্র সহ একটি .json ফাইল ডাউনলোড করবে৷ এই ফাইলটি একটি পরিচিত স্থানে সংরক্ষণ করুন।



এটাই! আমরা Firebase প্রমাণীকরণের সাথে Next.js অ্যাপকে সংহত করতে প্রস্তুত

স্ক্র্যাচ থেকে Next.js অ্যাপ তৈরি করা হচ্ছে

এই গাইড অনুমান করে যে আপনি Node.js এবং npm ইনস্টল করেছেন। এই টিউটোরিয়ালে ব্যবহৃত কমান্ডগুলি সর্বশেষ LTS Node.js v20 এর বিরুদ্ধে যাচাই করা হয়েছে। আপনি টার্মিনালে node -v চালিয়ে নোড সংস্করণ যাচাই করতে পারেন। আপনি Node.js সংস্করণগুলির মধ্যে দ্রুত স্যুইচ করতে NVM এর মতো সরঞ্জামগুলিও ব্যবহার করতে পারেন।

CLI এর সাথে Next.js অ্যাপ সেট আপ করা হচ্ছে

আপনার প্রিয় টার্মিনাল খুলুন, আপনার প্রকল্প ফোল্ডারে নেভিগেট করুন এবং চালান

 npx create-next-app@latest


এটি সহজ রাখতে, এর ডিফল্ট কনফিগারেশন ব্যবহার করা যাক। এর মানে আমরা TypeScript এবং tailwind ব্যবহার করব

 ✔ What is your project named? … my-app ✔ Would you like to use TypeScript? … Yes ✔ Would you like to use ESLint? … Yes ✔ Would you like to use Tailwind CSS? … Yes ✔ Would you like to use `src/` directory? … No ✔ Would you like to use App Router? (recommended) … Yes ✔ Would you like to customize the default import alias (@/*)? … No


আসুন প্রজেক্টের রুট ডিরে নেভিগেট করি এবং নিশ্চিত করুন যে সমস্ত নির্ভরতা ইনস্টল করা আছে

 cd my-app npm install


সবকিছু প্রত্যাশিতভাবে কাজ করছে তা নিশ্চিত করতে, npm run dev কমান্ড দিয়ে Next.js dev সার্ভার শুরু করা যাক। আপনি যখন http://localhost:3000 খুলবেন, তখন আপনাকে Next.js স্বাগত পৃষ্ঠা দেখতে হবে, এর অনুরূপ:


Next.js স্বাগতম পৃষ্ঠা

পরিবেশের ভেরিয়েবল প্রস্তুত করা হচ্ছে

আমরা Firebase এর সাথে একীভূত করা শুরু করার আগে, আমাদের Firebase কনফিগারেশন সংরক্ষণ এবং পড়ার জন্য একটি নিরাপদ উপায় প্রয়োজন। ভাগ্যক্রমে, Next.js বিল্ট-ইন dotenv সমর্থন সহ জাহাজ।


আপনার প্রিয় কোড এডিটর খুলুন এবং প্রোজেক্ট ফোল্ডারে নেভিগেট করুন


আসুন প্রজেক্টের রুট ডিরেক্টরিতে .env.local ফাইল তৈরি করি এবং নিম্নলিখিত এনভায়রনমেন্ট ভেরিয়েবল দিয়ে এটি পূরণ করি:


 FIREBASE_ADMIN_CLIENT_EMAIL=... FIREBASE_ADMIN_PRIVATE_KEY=... AUTH_COOKIE_NAME=AuthToken AUTH_COOKIE_SIGNATURE_KEY_CURRENT=secret1 AUTH_COOKIE_SIGNATURE_KEY_PREVIOUS=secret2 USE_SECURE_COOKIES=false NEXT_PUBLIC_FIREBASE_PROJECT_ID=... NEXT_PUBLIC_FIREBASE_API_KEY=AIza... NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN=....firebaseapp.com NEXT_PUBLIC_FIREBASE_DATABASE_URL=....firebaseio.com NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID=...


দয়া করে মনে রাখবেন যে NEXT_PUBLIC_ এর সাথে প্রিফিক্স করা ভেরিয়েবলগুলি ক্লায়েন্ট-সাইড বান্ডেলে উপলব্ধ হবে৷ Firebase Auth Client SDK সেটআপ করার জন্য আমাদের এগুলোর প্রয়োজন হবে


NEXT_PUBLIC_FIREBASE_PROJECT_ID , FIREBASE_ADMIN_CLIENT_EMAIL এবং FIREBASE_ADMIN_PRIVATE_KEY পরিষেবা অ্যাকাউন্টের শংসাপত্র তৈরি করার পরে ডাউনলোড করা .json ফাইল থেকে পুনরুদ্ধার করা যেতে পারে


AUTH_COOKIE_NAME ব্যবহারকারীর শংসাপত্র সংরক্ষণ করতে ব্যবহৃত কুকির নাম হবে৷

AUTH_COOKIE_SIGNATURE_KEY_CURRENT এবং AUTH_COOKIE_SIGNATURE_KEY_PREVIOUS হল গোপনীয়তা যেগুলির সাথে আমরা শংসাপত্রগুলিতে স্বাক্ষর করতে যাচ্ছি


NEXT_PUBLIC_FIREBASE_API_KEY হল ওয়েব API কী প্রকল্প সেটিংস সাধারণ পৃষ্ঠা থেকে পুনরুদ্ধার করা হয়েছে

NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN হল আপনার-project-id .firebaseapp.com

NEXT_PUBLIC_FIREBASE_DATABASE_URL হল আপনার-project-id .firebaseio.com

NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID প্রকল্প সেটিংস > ক্লাউড মেসেজিং পৃষ্ঠা থেকে প্রাপ্ত করা যেতে পারে


USE_SECURE_COOKIES স্থানীয় উন্নয়নের জন্য ব্যবহার করা হবে না, কিন্তু আমরা যখন Vercel-এ আমাদের অ্যাপ স্থাপন করব তখন কাজে আসবে

ফায়ারবেস প্রমাণীকরণের সাথে একীভূত করা

next-firebase-auth-edge এবং প্রাথমিক কনফিগারেশন ইনস্টল করা হচ্ছে

npm install next-firebase-auth-edge@^1.4.1 চালিয়ে প্রকল্পের নির্ভরতাগুলিতে লাইব্রেরি যুক্ত করুন


আমাদের প্রজেক্ট কনফিগারেশন এনক্যাপসুলেট করার জন্য config.ts ফাইল তৈরি করা যাক। এটির প্রয়োজন নেই, তবে কোড উদাহরণগুলি আরও পাঠযোগ্য করে তুলবে।

সেই মানগুলি নিয়ে চিন্তা করার জন্য খুব বেশি সময় ব্যয় করবেন না। আমরা অনুসরণ করার সাথে সাথে আমরা তাদের আরও বিস্তারিতভাবে ব্যাখ্যা করব।


 export const serverConfig = { cookieName: process.env.AUTH_COOKIE_NAME!, cookieSignatureKeys: [process.env.AUTH_COOKIE_SIGNATURE_KEY_CURRENT!, process.env.AUTH_COOKIE_SIGNATURE_KEY_PREVIOUS!], cookieSerializeOptions: { path: "/", httpOnly: true, secure: process.env.USE_SECURE_COOKIES === "true", sameSite: "lax" as const, maxAge: 12 * 60 * 60 * 24, }, serviceAccount: { projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID!, clientEmail: process.env.FIREBASE_ADMIN_CLIENT_EMAIL!, privateKey: process.env.FIREBASE_ADMIN_PRIVATE_KEY?.replace(/\\n/g, "\n")!, } }; export const clientConfig = { projectId: process.env.NEXT_PUBLIC_FIREBASE_PROJECT_ID, apiKey: process.env.NEXT_PUBLIC_FIREBASE_API_KEY!, authDomain: process.env.NEXT_PUBLIC_FIREBASE_AUTH_DOMAIN, databaseURL: process.env.NEXT_PUBLIC_FIREBASE_DATABASE_URL, messagingSenderId: process.env.NEXT_PUBLIC_FIREBASE_MESSAGING_SENDER_ID };


মিডলওয়্যার যোগ করা হচ্ছে

প্রজেক্টের রুটে middleware.ts ফাইল তৈরি করুন এবং নিম্নলিখিতটি পেস্ট করুন

 import { NextRequest } from "next/server"; import { authMiddleware } from "next-firebase-auth-edge"; import { clientConfig, serverConfig } from "./config"; export async function middleware(request: NextRequest) { return authMiddleware(request, { loginPath: "/api/login", logoutPath: "/api/logout", apiKey: clientConfig.apiKey, cookieName: serverConfig.cookieName, cookieSignatureKeys: serverConfig.cookieSignatureKeys, cookieSerializeOptions: serverConfig.cookieSerializeOptions, serviceAccount: serverConfig.serviceAccount, }); } export const config = { matcher: [ "/", "/((?!_next|api|.*\\.).*)", "/api/login", "/api/logout", ], };


বিশ্বাস করুন বা না করুন, কিন্তু আমরা আমাদের অ্যাপের সার্ভারকে Firebase প্রমাণীকরণের সাথে একত্রিত করেছি। আমরা আসলে এটি ব্যবহার করার আগে, আসুন কনফিগারেশনটি একটু ব্যাখ্যা করি:


loginPath authMiddleware কে GET /api/login এন্ডপয়েন্ট প্রকাশ করতে নির্দেশ দেবে। যখন এই এন্ডপয়েন্টটিকে Authorization: Bearer ${idToken} * হেডার, তখন এটি HTTP(S)-শুধুমাত্র Set-Cookie শিরোলেখ সহ স্বাক্ষরিত কাস্টম এবং রিফ্রেশ টোকেন সহ সাড়া দেয়


* Firebase ক্লায়েন্ট SDK- এ উপলব্ধ getIdToken ফাংশন দিয়ে idToken পুনরুদ্ধার করা হয়েছে। এই বিষয়ে পরে আরো.


একইভাবে, logoutPath মিডলওয়্যারকে GET /api/logout প্রকাশ করার নির্দেশ দেয়, তবে এটির জন্য কোনো অতিরিক্ত শিরোনামের প্রয়োজন নেই। কল করা হলে, এটি ব্রাউজার থেকে প্রমাণীকরণ কুকিগুলি সরিয়ে দেয়।


apiKey হল ওয়েব API কী। মিডলওয়্যার এটি ব্যবহার করে কাস্টম টোকেন রিফ্রেশ করতে এবং শংসাপত্রের মেয়াদ শেষ হয়ে যাওয়ার পরে প্রমাণীকরণ কুকি রিসেট করতে।


cookieName হল কুকি সেটের নাম এবং /api/login এবং /api/logout এন্ডপয়েন্ট দ্বারা মুছে ফেলা হয়


cookieSignatureKeys গোপন কীগুলির একটি তালিকা ব্যবহারকারীর শংসাপত্রগুলি স্বাক্ষরিত হয়। শংসাপত্রগুলি সর্বদা তালিকার প্রথম কী দিয়ে স্বাক্ষরিত হতে চলেছে, এইভাবে আপনাকে কমপক্ষে একটি মান প্রদান করতে হবে। আপনি একটি কী ঘূর্ণন সম্পাদন করতে একাধিক কী প্রদান করতে পারেন


cookieSerializeOptions হল Set-Cookie হেডার তৈরি করার সময় কুকিতে পাস করা বিকল্প। আরও তথ্যের জন্য কুকি README দেখুন


serviceAccount আপনার ফায়ারবেস পরিষেবাগুলি ব্যবহার করার জন্য লাইব্রেরি অনুমোদন করে৷


ম্যাচার Next.js সার্ভারকে মিডলওয়্যারকে /api/login , /api/logout , / এবং ফাইল বা এপিআই কল নয় এমন অন্য কোনো পাথ চালানোর নির্দেশ দেয়।

 export const config = { matcher: [ "/", "/((?!_next|api|.*\\.).*)", "/api/login", "/api/logout", ], };


আপনি হয়তো ভাবছেন কেন আমরা সমস্ত /api/* কলের জন্য মিডলওয়্যার সক্ষম করছি না। আমরা পারি, কিন্তু API রুট হ্যান্ডলারের মধ্যেই অননুমোদিত কলগুলি পরিচালনা করা একটি ভাল অনুশীলন। এই টিউটোরিয়ালের জন্য এটি কিছুটা সুযোগের বাইরে, তবে আপনি যদি আগ্রহী হন তবে আমাকে জানান এবং আমি কিছু উদাহরণ প্রস্তুত করব!



আপনি দেখতে পাচ্ছেন, কনফিগারেশনটি ন্যূনতম এবং স্পষ্টভাবে সংজ্ঞায়িত উদ্দেশ্য সহ। এখন, আসুন আমাদের /api/login এবং /api/logout এন্ডপয়েন্ট কল করা শুরু করি।


একটি নিরাপদ হোম পেজ তৈরি করা

জিনিসগুলি যতটা সম্ভব সহজ করার জন্য, আসুন ডিফল্ট Next.js হোম পেজটি পরিষ্কার করি এবং কিছু ব্যক্তিগতকৃত সামগ্রী দিয়ে এটি প্রতিস্থাপন করি


./app/page.tsx খুলুন এবং এটি পেস্ট করুন:

 import { getTokens } from "next-firebase-auth-edge"; import { cookies } from "next/headers"; import { notFound } from "next/navigation"; import { clientConfig, serverConfig } from "../config"; export default async function Home() { const tokens = await getTokens(cookies(), { apiKey: clientConfig.apiKey, cookieName: serverConfig.cookieName, cookieSignatureKeys: serverConfig.cookieSignatureKeys, serviceAccount: serverConfig.serviceAccount, }); if (!tokens) { notFound(); } return ( <main className="flex min-h-screen flex-col items-center justify-center p-24"> <h1 className="text-xl mb-4">Super secure home page</h1> <p> Only <strong>{tokens?.decodedToken.email}</strong> holds the magic key to this kingdom! </p> </main> ); }


এর বিট বিট এই নিচে ভাঙ্গা যাক.


getTokens ফাংশনটি কুকিজ থেকে ব্যবহারকারীর শংসাপত্র যাচাই এবং বের করার জন্য ডিজাইন করা হয়েছে

 const tokens = await getTokens(cookies(), { apiKey: clientConfig.apiKey, cookieName: serverConfig.cookieName, cookieSignatureKeys: serverConfig.cookieSignatureKeys, serviceAccount: serverConfig.serviceAccount, });


এটি null দিয়ে সমাধান করে, যদি ব্যবহারকারী অননুমোদিত হয়, বা দুটি বৈশিষ্ট্য ধারণকারী একটি বস্তু:


token যা idToken string যা আপনি বহিরাগত ব্যাকএন্ড পরিষেবাগুলিতে API অনুরোধগুলি অনুমোদন করতে ব্যবহার করতে পারেন। এটি কিছুটা সুযোগের বাইরে, তবে এটি উল্লেখ করা উচিত যে লাইব্রেরি বিতরণ করা পরিষেবা আর্কিটেকচার সক্ষম করে। token সামঞ্জস্যপূর্ণ এবং সমস্ত প্ল্যাটফর্মে সমস্ত অফিসিয়াল ফায়ারবেস লাইব্রেরির সাথে ব্যবহারের জন্য প্রস্তুত৷


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


tokens পাওয়ার পর, আমরা next/navigation থেকে notFound ফাংশন ব্যবহার করি যাতে নিশ্চিত করা যায় যে পৃষ্ঠাটি শুধুমাত্র প্রমাণীকৃত ব্যবহারকারীদের কাছে অ্যাক্সেসযোগ্য।

 if (!tokens) { notFound(); }


অবশেষে, আমরা কিছু মৌলিক, ব্যক্তিগতকৃত ব্যবহারকারীর সামগ্রী রেন্ডার করি

 <main className="flex min-h-screen flex-col items-center justify-center p-24"> <h1 className="text-xl mb-4">Super secure home page</h1> <p> Only <strong>{tokens?.decodedToken.email}</strong> holds the magic key to this kingdom!" </p> </main>


চলুন এটা চালানো যাক.

আপনি যদি আপনার dev সার্ভার বন্ধ করে থাকেন, তাহলে শুধু npm run dev চালান।


আপনি যখন http://localhost:3000/ অ্যাক্সেস করার চেষ্টা করেন, তখন আপনার দেখা উচিত 404: এই পৃষ্ঠাটি খুঁজে পাওয়া যায়নি।


সফলতার ! আমরা আমাদের গোপনীয়তা রক্ষা করেছি চোখ ধাঁধানো থেকে!


firebase ইনস্টল করা এবং ফায়ারবেস ক্লায়েন্ট SDK শুরু করা

প্রকল্পের রুট ডিরেক্টরিতে npm install firebase চালান


ক্লায়েন্ট SDK ইনস্টল করার পরে, প্রকল্প রুট ডিরেক্টরিতে firebase.ts ফাইল তৈরি করুন এবং নিম্নলিখিতটি পেস্ট করুন

 import { initializeApp } from 'firebase/app'; import { clientConfig } from './config'; export const app = initializeApp(clientConfig);


এটি ফায়ারবেস ক্লায়েন্ট SDK শুরু করবে এবং ক্লায়েন্ট উপাদানগুলির জন্য অ্যাপ অবজেক্টকে প্রকাশ করবে

একটি নিবন্ধন পৃষ্ঠা তৈরি করা হচ্ছে

সুপার সুরক্ষিত হোম পেজ থাকলে কি লাভ, যদি কেউ এটি দেখতে না পারে? লোকেদের আমাদের অ্যাপে প্রবেশ করতে দেওয়ার জন্য আসুন একটি সহজ নিবন্ধন পৃষ্ঠা তৈরি করি।


আসুন ./app/register/page.tsx এর অধীনে একটি নতুন, অভিনব পৃষ্ঠা তৈরি করি৷


 "use client"; import { FormEvent, useState } from "react"; import Link from "next/link"; import { getAuth, createUserWithEmailAndPassword } from "firebase/auth"; import { app } from "../../firebase"; import { useRouter } from "next/navigation"; export default function Register() { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [confirmation, setConfirmation] = useState(""); const [error, setError] = useState(""); const router = useRouter(); async function handleSubmit(event: FormEvent) { event.preventDefault(); setError(""); if (password !== confirmation) { setError("Passwords don't match"); return; } try { await createUserWithEmailAndPassword(getAuth(app), email, password); router.push("/login"); } catch (e) { setError((e as Error).message); } } return ( <main className="flex min-h-screen flex-col items-center justify-center p-8"> <div className="w-full bg-white rounded-lg shadow dark:border md:mt-0 sm:max-w-md xl:p-0 dark:bg-gray-800 dark:border-gray-700"> <div className="p-6 space-y-4 md:space-y-6 sm:p-8"> <h1 className="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white"> Pray tell, who be this gallant soul seeking entry to mine humble abode? </h1> <form onSubmit={handleSubmit} className="space-y-4 md:space-y-6" action="#" > <div> <label htmlFor="email" className="block mb-2 text-sm font-medium text-gray-900 dark:text-white" > Your email </label> <input type="email" name="email" value={email} onChange={(e) => setEmail(e.target.value)} id="email" className="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="[email protected]" required /> </div> <div> <label htmlFor="password" className="block mb-2 text-sm font-medium text-gray-900 dark:text-white" > Password </label> <input type="password" name="password" value={password} onChange={(e) => setPassword(e.target.value)} id="password" placeholder="••••••••" className="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" required /> </div> <div> <label htmlFor="confirm-password" className="block mb-2 text-sm font-medium text-gray-900 dark:text-white" > Confirm password </label> <input type="password" name="confirm-password" value={confirmation} onChange={(e) => setConfirmation(e.target.value)} id="confirm-password" placeholder="••••••••" className="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" required /> </div> {error && ( <div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert" > <span className="block sm:inline">{error}</span> </div> )} <button type="submit" className="w-full text-white bg-gray-600 hover:bg-gray-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-gray-600 dark:hover:bg-gray-700 dark:focus:ring-primary-800" > Create an account </button> <p className="text-sm font-light text-gray-500 dark:text-gray-400"> Already have an account?{" "} <Link href="/login" className="font-medium text-gray-600 hover:underline dark:text-gray-500" > Login here </Link> </p> </form> </div> </div> </main> ); }


আমি জানি. এটা অনেক টেক্সট, কিন্তু আমার সঙ্গে সহ্য.


আমরা "use client"; রেজিস্ট্রেশন পৃষ্ঠা ক্লায়েন্ট-সাইড API ব্যবহার করবে তা নির্দেশ করতে


 const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [confirmation, setConfirmation] = useState(""); const [error, setError] = useState("");

তারপর, আমরা আমাদের ফর্ম অবস্থা ধরে রাখতে কিছু ভেরিয়েবল এবং সেটারের সংজ্ঞায়িত করি


 const router = useRouter(); async function handleSubmit(event: FormEvent) { event.preventDefault(); setError(""); if (password !== confirmation) { setError("Passwords don't match"); return; } try { await createUserWithEmailAndPassword(getAuth(app), email, password); router.push("/login"); } catch (e) { setError((e as Error).message); } }

এখানে, আমরা আমাদের ফর্ম জমা দেওয়ার যুক্তি সংজ্ঞায়িত করি। প্রথমত, password এবং confirmation সমান হলে আমরা যাচাই করি, অন্যথায় আমরা ত্রুটির অবস্থা আপডেট করি। মানগুলি বৈধ হলে, আমরা firebase/auth থেকে createUserWithEmailAndPassword দিয়ে ব্যবহারকারীর অ্যাকাউন্ট তৈরি করি। যদি এই পদক্ষেপটি ব্যর্থ হয় (যেমন, ই-মেইল নেওয়া হয়েছে), আমরা ত্রুটি আপডেট করে ব্যবহারকারীকে জানাই।


সবকিছু ঠিকঠাক থাকলে, আমরা ব্যবহারকারীকে /login পৃষ্ঠায় পুনঃনির্দেশ করি। আপনি সম্ভবত এই মুহূর্তে বিভ্রান্ত, এবং আপনি তাই হতে সঠিক. /login পৃষ্ঠা এখনও বিদ্যমান নেই. আমরা শুধু পরবর্তী কি হতে চলেছে তার জন্য প্রস্তুত করছি.


আপনি যখন http://localhost:3000/register পরিদর্শন করেন, তখন পৃষ্ঠাটি মোটামুটি এইরকম দেখতে হবে:


নিবন্ধন পৃষ্ঠা


একটি লগইন পৃষ্ঠা তৈরি করা হচ্ছে

এখন, যে ব্যবহারকারীরা নিবন্ধন করতে সক্ষম, তাদের তাদের পরিচয় প্রমাণ করতে দিন


./app/login/page.tsx এর অধীনে একটি লগইন পৃষ্ঠা তৈরি করুন


 "use client"; import { FormEvent, useState } from "react"; import Link from "next/link"; import { useRouter } from "next/navigation"; import { getAuth, signInWithEmailAndPassword } from "firebase/auth"; import { app } from "../../firebase"; export default function Login() { const [email, setEmail] = useState(""); const [password, setPassword] = useState(""); const [error, setError] = useState(""); const router = useRouter(); async function handleSubmit(event: FormEvent) { event.preventDefault(); setError(""); try { const credential = await signInWithEmailAndPassword( getAuth(app), email, password ); const idToken = await credential.user.getIdToken(); await fetch("/api/login", { headers: { Authorization: `Bearer ${idToken}`, }, }); router.push("/"); } catch (e) { setError((e as Error).message); } } return ( <main className="flex min-h-screen flex-col items-center justify-center p-8"> <div className="w-full bg-white rounded-lg shadow dark:border md:mt-0 sm:max-w-md xl:p-0 dark:bg-gray-800 dark:border-gray-700"> <div className="p-6 space-y-4 md:space-y-6 sm:p-8"> <h1 className="text-xl font-bold leading-tight tracking-tight text-gray-900 md:text-2xl dark:text-white"> Speak thy secret word! </h1> <form onSubmit={handleSubmit} className="space-y-4 md:space-y-6" action="#" > <div> <label htmlFor="email" className="block mb-2 text-sm font-medium text-gray-900 dark:text-white" > Your email </label> <input type="email" name="email" value={email} onChange={(e) => setEmail(e.target.value)} id="email" className="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" placeholder="[email protected]" required /> </div> <div> <label htmlFor="password" className="block mb-2 text-sm font-medium text-gray-900 dark:text-white" > Password </label> <input type="password" name="password" value={password} onChange={(e) => setPassword(e.target.value)} id="password" placeholder="••••••••" className="bg-gray-50 border border-gray-300 text-gray-900 sm:text-sm rounded-lg focus:ring-primary-600 focus:border-primary-600 block w-full p-2.5 dark:bg-gray-700 dark:border-gray-600 dark:placeholder-gray-400 dark:text-white dark:focus:ring-blue-500 dark:focus:border-blue-500" required /> </div> {error && ( <div className="bg-red-100 border border-red-400 text-red-700 px-4 py-3 rounded relative" role="alert" > <span className="block sm:inline">{error}</span> </div> )} <button type="submit" className="w-full text-white bg-gray-600 hover:bg-gray-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-gray-600 dark:hover:bg-gray-700 dark:focus:ring-primary-800" > Enter </button> <p className="text-sm font-light text-gray-500 dark:text-gray-400"> Don&apos;t have an account?{" "} <Link href="/register" className="font-medium text-gray-600 hover:underline dark:text-gray-500" > Register here </Link> </p> </form> </div> </div> </main> ); }


আপনি দেখতে পাচ্ছেন, এটি নিবন্ধন পৃষ্ঠার মতোই। আসুন গুরুত্বপূর্ণ বিটে ফোকাস করা যাক:

 async function handleSubmit(event: FormEvent) { event.preventDefault(); setError(""); try { const credential = await signInWithEmailAndPassword( getAuth(app), email, password ); const idToken = await credential.user.getIdToken(); await fetch("/api/login", { headers: { Authorization: `Bearer ${idToken}`, }, }); router.push("/"); } catch (e) { setError((e as Error).message); } }


এটা যেখানে সব জাদু ঘটবে. আমরা ব্যবহারকারীর idToken পুনরুদ্ধার করতে firebase/auth থেকে signInEmailAndPassword ব্যবহার করি।


তারপর, আমরা মিডলওয়্যার দ্বারা উন্মুক্ত /api/login এন্ডপয়েন্টকে কল করি। এই শেষ পয়েন্ট ব্যবহারকারীর শংসাপত্র সহ আমাদের ব্রাউজার কুকিজ আপডেট করে।


অবশেষে, আমরা router.push("/");


লগইন পৃষ্ঠা মোটামুটি এই হিসাবে দেখতে হবে



এর এটা পরীক্ষা করা যাক!


http://localhost:3000/register এ যান, একটি অ্যাকাউন্ট তৈরি করতে কিছু এলোমেলো ই-মেইল ঠিকানা এবং পাসওয়ার্ড লিখুন। http://localhost:3000/login পৃষ্ঠায় সেই শংসাপত্রগুলি ব্যবহার করুন। আপনি এন্টার ক্লিক করার পরে, আপনাকে সুপার সুরক্ষিত হোম পেজে পুনঃনির্দেশিত করা উচিত


সুপার নিরাপদ হোম পেজ




আমরা অবশেষে আমাদের নিজস্ব , ব্যক্তিগত , অতি সুরক্ষিত হোম পেজ দেখতে পেয়েছি! কিন্তু অপেক্ষা করো! আমরা কিভাবে বের হতে পারি?


আমাদের একটি লগআউট বোতাম যুক্ত করতে হবে যাতে নিজেকে চিরতরে (বা 12 দিন) পৃথিবী থেকে লক আউট না করা যায়।


আমরা শুরু করার আগে, আমাদের একটি ক্লায়েন্ট উপাদান তৈরি করতে হবে যা Firebase ক্লায়েন্ট SDK ব্যবহার করে আমাদের সাইন আউট করতে সক্ষম হবে।


./app/HomePage.tsx এর অধীনে একটি নতুন ফাইল তৈরি করা যাক৷

 "use client"; import { useRouter } from "next/navigation"; import { getAuth, signOut } from "firebase/auth"; import { app } from "../firebase"; interface HomePageProps { email?: string; } export default function HomePage({ email }: HomePageProps) { const router = useRouter(); async function handleLogout() { await signOut(getAuth(app)); await fetch("/api/logout"); router.push("/login"); } return ( <main className="flex min-h-screen flex-col items-center justify-center p-24"> <h1 className="text-xl mb-4">Super secure home page</h1> <p className="mb-8"> Only <strong>{email}</strong> holds the magic key to this kingdom! </p> <button onClick={handleLogout} className="text-white bg-gray-600 hover:bg-gray-700 focus:ring-4 focus:outline-none focus:ring-primary-300 font-medium rounded-lg text-sm px-5 py-2.5 text-center dark:bg-gray-600 dark:hover:bg-gray-700 dark:focus:ring-primary-800" > Logout </button> </main> ); }


আপনি হয়তো লক্ষ্য করেছেন, এটি আমাদের ./app/page.tsx এর সামান্য পরিবর্তিত সংস্করণ। আমাদের একটি পৃথক ক্লায়েন্ট উপাদান তৈরি করতে হয়েছিল, কারণ getTokens শুধুমাত্র সার্ভার উপাদান এবং API রুট হ্যান্ডলারের মধ্যে কাজ করে, যখন signOut এবং useRouter ক্লায়েন্ট প্রসঙ্গে চালানোর প্রয়োজন হয়। একটু জটিল, আমি জানি, কিন্তু এটা আসলে বেশ শক্তিশালী। আমি পরে ব্যাখ্যা করব।


এর লগআউট প্রক্রিয়া ফোকাস করা যাক

 const router = useRouter(); async function handleLogout() { await signOut(getAuth(app)); await fetch("/api/logout"); router.push("/login"); }


প্রথমে, আমরা Firebase ক্লায়েন্ট SDK থেকে সাইন আউট করি। তারপর, আমরা মিডলওয়্যার দ্বারা প্রকাশিত /api/logout এন্ডপয়েন্টকে কল করি। আমরা ব্যবহারকারীকে /login পৃষ্ঠায় পুনঃনির্দেশ করে শেষ করি।


আমাদের সার্ভার হোম পেজ আপডেট করা যাক. ./app/page.tsx এ যান এবং নিম্নলিখিতটি পেস্ট করুন

 import { getTokens } from "next-firebase-auth-edge"; import { cookies } from "next/headers"; import { notFound } from "next/navigation"; import { clientConfig, serverConfig } from "../config"; import HomePage from "./HomePage"; export default async function Home() { const tokens = await getTokens(cookies(), { apiKey: clientConfig.apiKey, cookieName: serverConfig.cookieName, cookieSignatureKeys: serverConfig.cookieSignatureKeys, serviceAccount: serverConfig.serviceAccount, }); if (!tokens) { notFound(); } return <HomePage email={tokens?.decodedToken.email} />; }


এখন, আমাদের Home সার্ভার উপাদান শুধুমাত্র ব্যবহারকারীর টোকেন আনা এবং HomePage ক্লায়েন্ট কম্পোনেন্টে পাঠানোর জন্য দায়ী। এটি আসলে বেশ সাধারণ এবং দরকারী প্যাটার্ন।


আসুন এটি পরীক্ষা করা যাক:


ভয়লা ! আমরা এখন নিজের ইচ্ছায় অ্যাপ্লিকেশন থেকে লগইন এবং লগআউট করতে পারি। এটা নিখুঁত!

অথবা এটা?


যখন অননুমোদিত ব্যবহারকারী http://localhost:3000/ খুলে হোম পেজে প্রবেশ করার চেষ্টা করে তখন আমরা 404 দেখাই: এই পৃষ্ঠাটি খুঁজে পাওয়া যায়নি।

এছাড়াও, প্রমাণীকৃত ব্যবহারকারীরা এখনও লগ আউট না করেই http://localhost:3000/register এবং http://localhost:3000/login পৃষ্ঠা অ্যাক্সেস করতে সক্ষম।


আমরা আরও ভালো করতে পারি।


মনে হচ্ছে আমাদের কিছু পুনঃনির্দেশিত যুক্তি যোগ করতে হবে। আসুন কিছু নিয়ম সংজ্ঞায়িত করা যাক:

  • যখন প্রমাণীকৃত ব্যবহারকারী /register এবং /login পৃষ্ঠাগুলি অ্যাক্সেস করার চেষ্টা করে, তখন আমাদের তাদের / এ পুনঃনির্দেশ করা উচিত
  • যখন অননুমোদিত ব্যবহারকারী / পৃষ্ঠা অ্যাক্সেস করার চেষ্টা করে, তখন আমাদের তাদের /login এ পুনর্নির্দেশ করা উচিত


মিডলওয়্যার হল Next.js অ্যাপে রিডাইরেক্ট পরিচালনা করার অন্যতম সেরা উপায়। সৌভাগ্যবশত, authMiddleware বিস্তৃত পরিসরের পুনঃনির্দেশিত পরিস্থিতি পরিচালনা করতে সংখ্যক বিকল্প এবং সহায়ক ফাংশন সমর্থন করে।


আসুন middleware.ts ফাইলটি খুলি এবং এই আপডেট হওয়া সংস্করণটি পেস্ট করি

 import { NextRequest, NextResponse } from "next/server"; import { authMiddleware, redirectToHome, redirectToLogin } from "next-firebase-auth-edge"; import { clientConfig, serverConfig } from "./config"; const PUBLIC_PATHS = ['/register', '/login']; export async function middleware(request: NextRequest) { return authMiddleware(request, { loginPath: "/api/login", logoutPath: "/api/logout", apiKey: clientConfig.apiKey, cookieName: serverConfig.cookieName, cookieSignatureKeys: serverConfig.cookieSignatureKeys, cookieSerializeOptions: serverConfig.cookieSerializeOptions, serviceAccount: serverConfig.serviceAccount, handleValidToken: async ({token, decodedToken}, headers) => { if (PUBLIC_PATHS.includes(request.nextUrl.pathname)) { return redirectToHome(request); } return NextResponse.next({ request: { headers } }); }, handleInvalidToken: async (reason) => { console.info('Missing or malformed credentials', {reason}); return redirectToLogin(request, { path: '/login', publicPaths: PUBLIC_PATHS }); }, handleError: async (error) => { console.error('Unhandled authentication error', {error}); return redirectToLogin(request, { path: '/login', publicPaths: PUBLIC_PATHS }); } }); } export const config = { matcher: [ "/", "/((?!_next|api|.*\\.).*)", "/api/login", "/api/logout", ], };


এটাই হওয়া উচিত। আমরা সমস্ত পুনঃনির্দেশ বিধি প্রয়োগ করেছি৷ এর এই ভেঙ্গে দেওয়া যাক.


 const PUBLIC_PATHS = ['/register', '/login'];


 handleValidToken: async ({token, decodedToken}, headers) => { if (PUBLIC_PATHS.includes(request.nextUrl.pathname)) { return redirectToHome(request); } return NextResponse.next({ request: { headers } }); },

handleValidToken বলা হয় যখন অনুরোধের সাথে বৈধ ব্যবহারকারীর শংসাপত্র সংযুক্ত করা হয়, যেমন। ব্যবহারকারী প্রমাণীকৃত হয়। এটিকে প্রথম হিসাবে tokens অবজেক্ট এবং দ্বিতীয় আর্গুমেন্ট হিসাবে সংশোধিত অনুরোধ শিরোনাম দিয়ে বলা হয়। এটি NextResponse দিয়ে সমাধান করা উচিত।


next-firebase-auth-edge থেকে redirectToHome হল একটি সহায়ক ফাংশন যা একটি বস্তু ফেরত দেয় যা NextResponse.redirect(new URL(“/“)) এ সরলীকৃত করা যায়


PUBLIC_PATHS.includes(request.nextUrl.pathname) চেক করে, আমরা যাচাই করি যদি প্রমাণিত ব্যবহারকারী /login বা /register পৃষ্ঠা অ্যাক্সেস করার চেষ্টা করে, এবং যদি এমন হয় তবে হোমে পুনঃনির্দেশিত করি।



 handleInvalidToken: async (reason) => { console.info('Missing or malformed credentials', {reason}); return redirectToLogin(request, { path: '/login', publicPaths: PUBLIC_PATHS }); },


handleInvalidToken বলা হয় যখন প্রত্যাশিত কিছু ঘটে। এই প্রত্যাশিত ইভেন্টগুলির মধ্যে একটি হল ব্যবহারকারী আপনার অ্যাপটি প্রথমবার, অন্য ডিভাইস থেকে বা শংসাপত্রের মেয়াদ শেষ হয়ে যাওয়ার পরে।


অপ্রমাণিত ব্যবহারকারীর জন্য handleInvalidToken বলা হয়েছে জেনে, আমরা দ্বিতীয় নিয়মে এগিয়ে যেতে পারি: যখন অননুমোদিত ব্যবহারকারী / পৃষ্ঠা অ্যাক্সেস করার চেষ্টা করে, তখন আমাদের উচিত তাদের /login এ পুনঃনির্দেশ করা।


যেহেতু পূরণ করার জন্য অন্য কোন শর্ত নেই, আমরা শুধু redirectToLogin এর ফলাফল ফেরত দিই যা NextResponse.redirect(new URL(“/login”)) এ সরলীকৃত করা যেতে পারে। এটি নিশ্চিত করে যে ব্যবহারকারী রিডাইরেক্ট লুপে পড়ে না।


সবশেষে,

 handleError: async (error) => { console.error('Unhandled authentication error', {error}); return redirectToLogin(request, { path: '/login', publicPaths: PUBLIC_PATHS }); }


handleInvalidToken এর বিপরীতে, handleError বলা হয় যখন কিছু অপ্রত্যাশিত* ঘটে এবং সম্ভবত তদন্ত করা প্রয়োজন। আপনি ডকুমেন্টেশনে তাদের বর্ণনা সহ সম্ভাব্য ত্রুটিগুলির একটি তালিকা খুঁজে পেতে পারেন


একটি ত্রুটির ক্ষেত্রে, আমরা এই সত্যটি লগ করি এবং নিরাপদে ব্যবহারকারীকে লগইন পৃষ্ঠায় পুনঃনির্দেশ করি


* Google পাবলিক কীগুলি আপডেট করার পরে INVALID_ARGUMENT ত্রুটি সহ handleError কল করা যেতে পারে৷

এটি কী ঘূর্ণনের একটি রূপ এবং প্রত্যাশিতআরও তথ্যের জন্য এই Github সমস্যা দেখুন


এখন, এটাই। অবশেষে.


আসুন আমাদের ওয়েব অ্যাপ থেকে লগ-আউট করি এবং http://localhost:3000/ খুলি। আমাদের /login পৃষ্ঠায় পুনঃনির্দেশিত করা উচিত।

আসুন আবার লগ ইন করি, এবং http://localhost:3000/login প্রবেশ করার চেষ্টা করি। আমাদের / পৃষ্ঠায় পুনঃনির্দেশিত করা উচিত।


আমরা শুধু বিরামহীন ব্যবহারকারীর অভিজ্ঞতা প্রদান করি না। next-firebase-auth-edge হল শূন্য-বান্ডেল আকারের লাইব্রেরি যা শুধুমাত্র অ্যাপের সার্ভারে কাজ করে এবং অতিরিক্ত ক্লায়েন্ট-সাইড কোড প্রবর্তন করে না। ফলে বান্ডিল সত্যিই ন্যূনতম . সেটাকেই আমি নিখুঁত বলি।


আমাদের অ্যাপটি এখন সার্ভার এবং ক্লায়েন্ট উভয় উপাদানেই ফায়ারবেস প্রমাণীকরণের সাথে সম্পূর্ণরূপে একত্রিত। আমরা Next.js এর পূর্ণ সম্ভাবনা উন্মোচন করতে প্রস্তুত!




অ্যাপের সোর্স কোড নেক্সট-ফায়ারবেস-অথ-এজ/উদাহরণ/পরবর্তী-টাইপস্ক্রিপ্ট-মিনিমাল- এ পাওয়া যাবে


উপসংহার

এই নির্দেশিকায়, আমরা Firebase প্রমাণীকরণের সাথে নতুন Next.js অ্যাপকে একীভূত করার মাধ্যমে চলেছি।


যদিও বেশ বিস্তৃত, নিবন্ধটি প্রমাণীকরণ প্রবাহের কিছু গুরুত্বপূর্ণ অংশ বাদ দিয়েছে, যেমন পাসওয়ার্ড রিসেট ফর্ম বা ইমেল এবং পাসওয়ার্ড ছাড়া সাইন ইন পদ্ধতি।


আপনি যদি লাইব্রেরিতে আগ্রহী হন, আপনি পূর্ণাঙ্গ পরবর্তী-ফায়ারবেস-অথ-এজ স্টার্টার ডেমো পৃষ্ঠার পূর্বরূপ দেখতে পারেন।

এতে ফায়ারস্টোর ইন্টিগ্রেশন , সার্ভার অ্যাকশন , অ্যাপ-চেক সমর্থন এবং আরও অনেক কিছু রয়েছে


লাইব্রেরি প্রচুর উদাহরণ সহ একটি উত্সর্গীকৃত ডকুমেন্টেশন পৃষ্ঠা সরবরাহ করে


আপনি যদি নিবন্ধটি পছন্দ করেন, আমি পরবর্তী-ফায়ারবেস-অথ-এজ রিপোজিটরিতে অভিনয় করার প্রশংসা করব। চিয়ার্স! 🎉



বোনাস – ভার্সেলে অ্যাপ স্থাপন করা হচ্ছে

এই বোনাস নির্দেশিকা আপনাকে শেখাবে কিভাবে আপনার Next.js অ্যাপকে Vercel-এ স্থাপন করতে হয়

গিট সংগ্রহস্থল তৈরি করা হচ্ছে

Vercel এ স্থাপন করতে সক্ষম হতে, আপনাকে আপনার নতুন অ্যাপের জন্য একটি সংগ্রহস্থল তৈরি করতে হবে।


https://github.com/ এ যান এবং একটি নতুন সংগ্রহস্থল তৈরি করুন।


create-next-app ইতিমধ্যেই আমাদের জন্য একটি স্থানীয় গিট সংগ্রহস্থল শুরু করেছে, তাই আপনাকে কেবল আপনার প্রকল্পের রুট ফোল্ডারে অনুসরণ করতে হবে এবং চালাতে হবে:


 git add --all git commit -m "first commit" git branch -M main git remote add origin [email protected]:path-to-your-new-github-repository.git git push -u origin main


নতুন Vercel প্রকল্প যোগ করা হচ্ছে

https://vercel.com/ এ যান এবং আপনার Github অ্যাকাউন্ট দিয়ে সাইন ইন করুন


আপনি লগ ইন করার পরে, Vercel এর ওভারভিউ পৃষ্ঠাতে যান এবং নতুন > প্রকল্প যোগ করুন ক্লিক করুন


আমরা এইমাত্র তৈরি করা Github সংগ্রহস্থলের পাশে আমদানিতে ক্লিক করুন। এখনও স্থাপন করবেন না.


আমরা স্থাপন করার আগে, আমাদের প্রকল্প কনফিগারেশন প্রদান করতে হবে। আসুন কিছু পরিবেশের ভেরিয়েবল যোগ করি:

Vercel-এ স্থাপন করা হচ্ছে


USE_SECURE_COOKIES true সেট করতে মনে রাখবেন, যেহেতু Vercel ডিফল্টরূপে HTTPS ব্যবহার করে


এখন, আমরা Deploy এ ক্লিক করতে প্রস্তুত


এক বা দুই মিনিট অপেক্ষা করুন, এবং আপনি এটির মতো ইউআরএল দিয়ে আপনার অ্যাপ অ্যাক্সেস করতে সক্ষম হবেন: https://next-typescript-minimal-xi.vercel.app/


সম্পন্ন. আমি বাজি ধরে বলতে পারি আপনি এটি এত সহজ হবে বলে আশা করেননি।




আপনি যদি গাইডটি পছন্দ করেন, আমি পরবর্তী-ফায়ারবেস-অথ-এজ রিপোজিটরিতে অভিনয় করার প্রশংসা করব।


আপনি আমাকে মন্তব্যে আপনার প্রতিক্রিয়া জানাতে পারেন. চিয়ার্স! 🎉