Next.js Authentication Sinhala Guide | NextAuth.js, Custom Auth, Security Best Practices

Next.js Authentication Sinhala Guide | NextAuth.js, Custom Auth, Security Best Practices

ආයුබෝවන් යාළුවනේ! වෙබ් ඩිවලොප්මන්ට් (Web Development) වලදී ගොඩක් වැදගත් වෙන, ඒ වගේම ටිකක් සංකීර්ණ වෙන්න පුළුවන් මාතෘකාවක් ගැන අද අපි කතා කරමු – ඒ තමයි Authentication. සරලව කිව්වොත්, ඔයාගේ වෙබ්සයිට් එකට එන කෙනා කවුද කියලා තහවුරු කරගැනීම.

අද කාලේ ගොඩක් ජනප්‍රිය Framework එකක් වෙන Next.js වල, User Experience (UX) එකයි, Security එකයි දෙකම හොඳට Maintain කරන්න නම්, ශක්තිමත් Authentication System එකක් අනිවාර්යයි. මේ Guide එකෙන් අපි Next.js Project එකකදී Authentication එකක් Implement කරන්න ඕන කරන මූලික සංකල්ප (Core Concepts) වල ඉඳලා, ප්‍රායෝගික Strategies (Strategies) සහ හොඳම ක්‍රියාකාරීත්වයන් (Best Practices) දක්වා හැමදෙයක්ම සිංහලෙන් කතා කරමු.

මේ ලිපිය කියවන ඔයාට Next.js Project එකකදී User Login, Register වගේ දේවල් හදන්න පැහැදිලි අවබෝධයක් ලැබෙයි කියලා මම හිතනවා. එහෙනම්, අපි පටන් ගමු!

1. Authentication වල මූලික සංකල්ප (Core Authentication Concepts)

Next.js වලට යන්න කලින්, Authentication වල මූලික හරය අවබෝධ කරගැනීම ගොඩක් වැදගත්. අපි මුලින්ම ඒ ගැන බලමු.

1.1. Authentication කියන්නේ මොකක්ද?

සරලවම කියනවා නම්, Authentication කියන්නේ "ඔබ කවුදැයි තහවුරු කිරීමේ ක්‍රියාවලිය (verifying who you are)". ඔයාගේ User Name එකයි Password එකයි හරියට දීලා වෙබ්සයිට් එකකට ලොග් වෙනකොට, වෙබ්සයිට් එක ඔයාව 'Authenticate' කරනවා. ඊට පස්සේ තමයි ඔයාට ඒකේ තියෙන Protected Content වලට Access කරන්න පුළුවන් වෙන්නේ.

1.2. Session-based Authentication

මේක තමයි කලින් කාලේ ගොඩක් ජනප්‍රිය වෙලා තිබුණු ක්‍රමය. User කෙනෙක් සාර්ථකව Login වුණාට පස්සේ,

  • Server එක Unique Session ID එකක් Generate කරනවා.
  • මේ Session ID එක Server එකේ Database එකක හෝ Memory එකක Store කරලා තියාගන්නවා (මේකට තමයි User State Maintain කරනවා කියන්නේ).
  • ඊට පස්සේ මේ Session ID එක Client-side එකට Cookie එකක් විදිහට යවනවා.
  • Client-side එක හැම Request එකක් එක්කම මේ Cookie එක Server එකට යවනවා. Server එක මේ Cookie එකේ තියෙන Session ID එක තමන්ගේ Store කරලා තියෙන ID එක එක්ක Compare කරලා User ව Identify කරනවා.

වාසි (Pros): ක්‍රියාත්මක කරන්න සරලයි, විශේෂයෙන්ම Single Server Application වලට.

අවාසි (Cons): Distributed Systems (Microservices) වලට හෝ API වලට එච්චර ගැලපෙන්නේ නෑ, Server එකට User State Maintain කරන්න වෙන නිසා Scalability එක අඩුයි.

1.3. Token-based Authentication (විශේෂයෙන්ම JWT)

අද කාලේ ගොඩක්ම ජනප්‍රිය ක්‍රමය තමයි Token-based Authentication. මේක Stateless ක්‍රමයක්. ඒ කියන්නේ Server එක User State Maintain කරන්නේ නෑ.

  • User සාර්ථකව Login වුණාට පස්සේ, Server එක Token එකක් (ගොඩක් වෙලාවට JWT - JSON Web Token එකක්) Generate කරලා Client එකට යවනවා.
  • Client එක මේ Token එක (Local Storage, Session Storage හෝ Cookies වල) Store කරලා තියාගන්නවා.
  • ඊට පස්සේ හැම Protected Request එකක් එක්කම මේ Token එක Request Header එකේ (සාමාන්‍යයෙන් Authorization: Bearer <token> විදිහට) Server එකට යවනවා.
  • Server එකට මේ Token එක ලැබුණාම, ඒක Verify කරලා (Digital Signature එක Check කරලා) User කවුද, ඒ User ට මොනවාට Access කරන්න පුළුවන්ද කියලා තීරණය කරනවා.

JWT එකක මූලික කොටස් 3ක් තියෙනවා:

  1. Header: Token එකේ Type එකයි, Sign කරන්න පාවිච්චි කරන Hashing Algorithm එකයි තියෙනවා.
  2. Payload: User ID, Role, Expiration Time වගේ Actual Data (Claims) තියෙනවා. මේක Encrypted නෑ, Base64 Encoded විතරයි.
  3. Signature: Header එකයි, Payload එකයි, Server Secret එකකුයි පාවිච්චි කරලා හදන Hash එකක්. මේකෙන් Token එක Valid ද, Modify කරලා නැද්ද කියලා Check කරනවා.

වාසි (Pros): Scalable (Server එකට State මතක තියාගන්න ඕනේ නැති නිසා), Mobile Applications සහ APIs වලට ගොඩක් ගැලපෙනවා.

අවාසි (Cons): Token එක Client-side එකේ Store කරන නිසා Security ගැන සැලකිලිමත් වෙන්න ඕන, Token එක Revoke (Invalid) කරන එක ටිකක් සංකීර්ණ වෙන්න පුළුවන්.

1.4. OAuth (Open Authorization)

OAuth කියන්නේ Authentication වලට වඩා Authorization Framework එකක්. මේකෙන් කරන්නේ User ගේ Credentials (Username, Password) share නොකර, Third-party Applications වලට User ගේ Data වලට Access කරන්න අවසර දෙන එක. උදාහරණයක් විදිහට, ඔයා වෙබ්සයිට් එකකට "Login with Google" හෝ "Login with Facebook" කියන Options පාවිච්චි කරනකොට මේ OAuth තමයි ක්‍රියාත්මක වෙන්නේ.

  • ඔයා Third-party Provider (Google, Facebook) හරහා Login කරනවා.
  • Provider එක ඔයාව Authenticate කරලා, ඔයාගේ අවසරය ඇතුව, Client Application එකට Access Token එකක් දෙනවා.
  • මේ Access Token එක පාවිච්චි කරලා Client Application එකට Provider ගේ API එකෙන් ඔයාගේ Data වලට (e.g., Email, Profile Picture) Access කරන්න පුළුවන් වෙනවා.

වාසි (Pros): User Experience එක හොඳයි (Register වෙන්න ඕනේ නෑ), Security වැඩි (Credentials share වෙන්නේ නෑ), Developer ට Authentication logic ලියන්න වෙන කාලය අඩුයි.

අවාසි (Cons): Implement කරන්න ටිකක් සංකීර්ණ වෙන්න පුළුවන්, Third-party Provider එක මත රඳා පවතිනවා.

2. Next.js වල Authentication Strategies (Strategies in Next.js)

දැන් අපි Next.js Project එකකදී මේ Authentication Concepts Implement කරන්න පුළුවන් Strategies මොනවද කියලා බලමු.

2.1. NextAuth.js (නිර්දේශිතයි - Recommended)

Next.js Project වලට Authentication එකක් හදන්න තියෙන හොඳම සහ ජනප්‍රියම Library එක තමයි NextAuth.js. මේක Next.js වලටම විශේෂයෙන් හදපු, සම්පූර්ණ (Full-stack) Authentication Solution එකක්.

NextAuth.js වල විශේෂාංග:

  • විවිධ Providers: Google, Facebook, GitHub වගේ OAuth Providers 50කට වඩා Support කරනවා. Credentials (Email/Password) සහ Email (Magic Links) Login වලටත් Support කරනවා.
  • Session Management: JWT හෝ Database Sessions දෙකටම Support කරනවා.
  • Callbacks: Login, Logout වගේ Events වලදී Custom Logic Add කරන්න පුළුවන්.
  • Database Integration: Adapters පාවිච්චි කරලා Prisma, MongoDB, PostgreSQL වගේ Databases එක්ක පහසුවෙන් Integrate කරන්න පුළුවන්.
  • Zero Configuration API Routes: Authentication API endpoints ටික Next.js API Routes විදිහට Auto Generate කරනවා.

ප්‍රායෝගික උදාහරණය: NextAuth.js මූලික සැකසීම (Basic Setup)

Next.js Project එකකට NextAuth.js Add කරන්නේ කොහොමද කියලා අපි සරල උදාහරණයකින් බලමු.

Client-side එකේ Usage:දැන් ඔයාට ඕනෑම Component එකකදී User ගේ Session එකට Access කරන්න, Login/Logout කරන්න පුළුවන්.

// components/Header.js

import { useSession, signIn, signOut } from 'next-auth/react';

export default function Header() {
  const { data: session } = useSession();

  if (session) {
    return (
      <div>
        <p>Welcome, {session.user.name}!</p>
        <button onClick={() => signOut()}>Sign out</button>
      </div>
    );
  }
  return (
    <div>
      <p>You are not signed in.</p>
      <button onClick={() => signIn()}>Sign in</button>
    </div>
  );
}

Client-side එකේ Provider Set up කිරීම:ඔයාගේ pages/_app.js File එකේ SessionProvider එකෙන් App එක Wrap කරන්න. මේකෙන් Client-side එකේ Authentication State එකට Access කරන්න පුළුවන්.

// pages/_app.js

import '../styles/globals.css';
import { SessionProvider } from 'next-auth/react';

function MyApp({ Component, pageProps: { session, ...pageProps } }) {
  return (
    <SessionProvider session={session}>
      <Component {...pageProps} />
    </SessionProvider>
  );
}

export default MyApp;

API Route එකක් හැදීම:pages/api/auth/[...nextauth].js කියන Path එකේ File එකක් හදන්න. මේක තමයි NextAuth.js Backend එක. [...] කියන්නේ Dynamic Route එකක්, ඒකෙන් NextAuth.js වලට අවශ්‍ය හැම Endpoint එකක්ම Handle කරනවා.

// pages/api/auth/[...nextauth].js

import NextAuth from "next-auth";
import GoogleProvider from "next-auth/providers/google";
import GitHubProvider from "next-auth/providers/github";

export default NextAuth({
  // Configure one or more authentication providers
  providers: [
    GoogleProvider({
      clientId: process.env.GOOGLE_CLIENT_ID,
      clientSecret: process.env.GOOGLE_CLIENT_SECRET,
    }),
    GitHubProvider({
      clientId: process.env.GITHUB_CLIENT_ID,
      clientSecret: process.env.GITHUB_CLIENT_SECRET,
    }),
    // Add more providers here
  ],
  // Optional: Configure database for persistent sessions
  // database: process.env.DATABASE_URL,
  // Optional: JWT options
  jwt: {
    secret: process.env.JWT_SECRET,
  },
  // Optional: Callbacks
  callbacks: {
    async session({ session, token, user }) {
      // Send properties to the client, like an access_token from a provider.
      // session.accessToken = token.accessToken; // Example
      return session;
    },
  },
  // A database is optional, but required to persist sessions in a database
  // database: process.env.DATABASE_URL,
});

මෙහිදී process.env.GOOGLE_CLIENT_ID වගේ Environment Variables ටික .env.local File එකේ සකස් කරන්න ඕනේ. ඒවා ඒ Provider (Google, GitHub) ගේ Developer Console එකෙන් ලබාගන්න පුළුවන්.

NextAuth.js Install කිරීම:

npm install next-auth
# හෝ
yarn add next-auth

මේ සරල Set up එකෙන් ඔයාට Google හෝ GitHub හරහා Login/Logout කරන්න පුළුවන් වෙනවා.

2.2. Custom Solutions

සමහර වෙලාවට NextAuth.js ඔයාගේ Project එකට ගැලපෙන්නේ නැති වෙන්න පුළුවන් (Custom Requirements, Specific Database Setups, Existing Backend Systems වගේ දේවල් නිසා). එතකොට Custom Solution එකකට යන්න වෙනවා.

  • Passport.js (Node.js): Node.js වලට තියෙන ජනප්‍රිය Middleware එකක්. Next.js API Routes පාවිච්චි කරලා ඔයාට Passport.js Implement කරන්න පුළුවන්. Backend එක සම්පූර්ණයෙන්ම ඔයාගේ Control එකේ තියාගන්න ඕන නම් මේක හොඳ Option එකක්.
  • Firebase Authentication: Google Ecosystem එකේ ඉන්න අයට Firebase Auth කියන්නේ Serverless Solution එකක්. Email/Password, Phone Number, Google, Facebook වගේ දේවල් හරහා User ව Authenticate කරන්න පුළුවන්. මේක Next.js Client-side එකේ සහ API Routes වලදී Use කරන්න පුළුවන්.
  • Clerk, Auth0, Okta: මේවා Third-party Managed Authentication Services. මේවා පාවිච්චි කරනකොට, Authentication Logic එක Handling කරන්නේ එයාලා. ඔයාට කරන්න තියෙන්නේ ඒවා Next.js Project එකට Integrate කරන එක විතරයි. මේවා ඉක්මනට Implement කරන්න පුළුවන් වුණාට, Cost එකක් තියෙන්න පුළුවන්.

Custom Solution එකක් පාවිච්චි කරනකොට, Server-side Logic එක Next.js API Routes වල ලියන්න වෙනවා. JWT Tokens Generate කිරීම, Verify කිරීම, Password Hashing වගේ හැම දෙයක්ම ඔයාටම Handle කරන්න සිද්ධ වෙනවා. මේකෙදි Security Best Practices ගැන ගොඩක් සැලකිලිමත් වෙන්න ඕනේ.

3. ආරක්ෂාව සහ හොඳ පුරුදු (Security and Best Practices)

Authentication System එකක් හදනකොට Security කියන්නේ කතා නොකරම බැරි මාතෘකාවක්. වැරදීම් නිසා වෙන්න පුළුවන් හානිය ගොඩක් ලොකුයි. ඒ නිසා මේ දේවල් ගැන ගොඩක් සැලකිලිමත් වෙන්න.

3.1. HTTPS අනිවාර්යයි (Always Use HTTPS)

ඔයාගේ වෙබ්සයිට් එක හැමවිටම HTTPS (SSL/TLS) හරහා Serve කරන්න. මේකෙන් Client Browser එකයි Server එකයි අතර යන හැම Data එකක්ම Encrypt කරනවා. ඒ නිසා Man-in-the-Middle Attacks වලින් ආරක්ෂා වෙන්න පුළුවන්. User Credentials, Session Cookies, JWT Tokens වගේ දේවල් HTTPS නැතුව යවන එක හරියට open book එකක් පාරේ ගෙනියනවා වගේ දෙයක්.

3.2. Passwords Hashing කිරීම

කවදාවත් User Passwords Plain Text විදිහට Database එකේ Store කරන්න එපා. හැමවිටම Strong Hashing Algorithm එකක් (උදාහරණයක් විදිහට bcrypt හෝ Argon2) පාවිච්චි කරලා Hash කරන්න. මේකෙන් Database Breach එකක් වුණත්, Attacker කෙනෙක්ට Passwords පහසුවෙන් කියවන්න බැරි වෙනවා.

// Example using bcrypt (Install: npm install bcryptjs)
import bcrypt from 'bcryptjs';

async function hashPassword(password) {
  const salt = await bcrypt.genSalt(10); // Generate a salt (random string)
  const hashedPassword = await bcrypt.hash(password, salt);
  return hashedPassword;
}

async function comparePassword(password, hashedPassword) {
  return await bcrypt.compare(password, hashedPassword);
}

3.3. Sensitive Data Client-side එකේ තියන්න එපා

User ගේ ID එක, Username එක වගේ දේවල් Client-side එකේ (Local Storage) තියාගත්තට කමක් නැති වුණාට, Role, Permissions, Access Tokens වගේ Sensitive Data කවදාවත් Client-side Storage එකක (Local Storage, Session Storage) තියන්න එපා. XSS (Cross-Site Scripting) Attack එකකින් ඒ Data හොරාගන්න පුළුවන්.

JWT Access Tokens Short-lived කරන්න, Refresh Tokens හැමවිටම HTTP-only cookies වල තියන්න. මේකෙන් JavaScript හරහා Token එකට Access කරන එක නවත්වනවා.

3.4. JWT Token Security

  • Short-lived Access Tokens: Access Tokens වලට කෙටි Expiration Time එකක් (minutes to a few hours) දෙන්න.
  • Secure Refresh Tokens: Refresh Tokens සාමාන්‍යයෙන් දීර්ඝ කාලයක් (days/weeks) වලංගුයි. මේවා HTTP-only, Secure Cookies වල Store කරන්න. Refresh Token එකකින් අලුත් Access Token එකක් ගන්න පුළුවන්.
  • Token Revocation: User කෙනෙක් Logout වුණාම හෝ Password එක Change කරාම, අදාළ Refresh Token එක Database එකෙන් Invalid කරන්න.

3.5. Cross-Site Request Forgery (CSRF) Protection

CSRF Attack එකකින් වෙන්නේ, Attacker කෙනෙක් User ව රවට්ටලා, User ගේ Login වෙලා තියෙන වෙබ්සයිට් එකට හානිකර Request එකක් යවන එක. NextAuth.js වගේ Libraries මේවා Auto Handle කරනවා. Custom Solution එකක් නම්, CSRF Tokens පාවිච්චි කරන්න ඕනේ. හැම Form Submission එකක් එක්කම Unique, Secret Token එකක් Server එකට යවලා Valid කරන්න.

3.6. Input Validation සහ Sanitization

User ගෙන් එන හැම Input එකක්ම (Email, Password, Username) Server-side එකේදී හොඳින් Validate කරන්න සහ Sanitize කරන්න. මේකෙන් SQL Injection, XSS (Cross-Site Scripting) වගේ Attacks වලින් ආරක්ෂා වෙන්න පුළුවන්. Empty fields, Special Characters, Max Length වගේ දේවල් Check කරන්න.

3.7. Rate Limiting

Login Attempts වලට Rate Limiting එකක් දාන්න. ඒ කියන්නේ, යම්කිසි කාලයක් ඇතුලත එකම IP Address එකකින් හෝ Username එකකින් කරන්න පුළුවන් Login Attempts ගණන සීමා කරන්න. මේකෙන් Brute-force Attacks වලින් ආරක්ෂා වෙන්න පුළුවන්.

නිගමනය (Conclusion)

Next.js Project එකක සාර්ථක Authentication System එකක් හදන එක කියන්නේ User Experience එකටයි, Application Security එකටයි දෙකටම ගොඩක් වැදගත් දෙයක්. Session-based, Token-based, OAuth වගේ මූලික සංකල්ප අවබෝධ කරගෙන, ඔයාගේ Project එකට ගැලපෙනම Strategy එක (ගොඩක් වෙලාවට NextAuth.js තමයි හොඳම Option එක) තෝරගන්න එක තමයි වැදගත්ම දේ.

ඒ වගේම HTTPS, Password Hashing, Token Security, Input Validation වගේ Security Best Practices ගැන හැමවිටම සැලකිලිමත් වෙන්න. මේ දේවල් හොඳින් Follow කරනවා නම්, ඔයාට ආරක්ෂිත සහ User Friendly Application එකක් හදන්න පුළුවන්.

දැන් ඔයාට Next.js Project එකකදී Authentication එකක් Implement කරන්න හොඳ අවබෝධයක් ලැබෙන්න ඇති කියලා මම හිතනවා. මේ Concept ටික ඔයාගේ ඊළඟ Project එකේදී Try කරලා බලන්න. ඔයාලගේ අත්දැකීම්, ප්‍රශ්න හෝ අදහස් පහල Comment Section එකේ Share කරන්න! ඔයාලගේ Coding Journey එකට සුබ පැතුම්!