Home SOFTWAREPomoć i savetiArhitektura modernih web aplikacija – Deo 8: Autentifikacija i autorizacija (AuthN/AuthZ)

Arhitektura modernih web aplikacija – Deo 8: Autentifikacija i autorizacija (AuthN/AuthZ)

od itn
Arhitektura modernih web aplikacija

Dobrodošli u osmi deo serijala na ITNetwork.rs! Do sada smo prošli kroz monolit i mikroservise, frontend arhitekturu, API-je, baze, mikroservise, serverless, i performanse. Danas ulazimo u najosetljiviju tačku svake aplikacije – bezbednost korisnika. Naučićemo kako pravilno implementirati autentifikaciju (AuthN) i autorizaciju (AuthZ), koristeći moderne standarde poput JWT, OAuth2, OpenID Connect, Passkeys i RBAC/ABAC.

Šta je AuthN, a šta AuthZ?

Pojam Pitanje Primer
AuthN (Autentifikacija) „Ko si ti?“ Login sa emailom/lozinkom
AuthZ (Autorizacija) „Šta smeš da radiš?“ Admin vidi /admin, korisnik ne

Loša bezbednost = kraj projekta.

1. Tradicionalni pristupi – lozinke i sesije

Problemi:

  • Lozinke se čuvaju u bazi → rizik od breach-a
  • Sesije zahtevaju server state → teško skaliranje
  • Phishing napadi

Rešenje: Hash-ovanje lozinki

import bcrypt from 'bcrypt';

const saltRounds = 12;
const hash = await bcrypt.hash(password, saltRounds);
const match = await bcrypt.compare(password, storedHash);

Nikad ne čuvaj plain-text lozinke!

2. JWT (JSON Web Tokens) – stateless autentifikacija

Kako radi?

JSON Web Tokens

Struktura JWT-a

eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJzdWIiOiIxMjMiLCJyb2xlIjoiYWRtaW4iLCJpYXQiOjE3MDAwMDAwMDAsImV4cCI6MTcwMDAwMzYwMH0.
signature
Prednosti
+ Objašnjenje
Stateless Nema sesije u bazi
Skalabilan Bilo koji server može proveriti
Frontend-friendly Čuva se u localStorage ili HttpOnly cookie
Mane
Objašnjenje
Ne može se opozvati Samo čekanjem na exp
Veliki token Ako ima mnogo claim-ova
localStorage rizik XSS napad
3. OAuth2 + OpenID Connect – standard za treće strane

Kada koristiti?

  • „Login sa Google/Facebook/GitHub“
  • Mobilne aplikacije
  • B2B integracije

Flow (Authorization Code + PKCE)

Authorization Code + PKCE

Alati

Alat Namena
Auth0 Kompletan IdP
Keycloak Open-source, self-hosted
NextAuth.js Next.js integracija
Supabase Auth PostgreSQL + GoTrue
4. Moderne metode – Passwordless, Magic Links, Passkeys

1. Magic Link

Pošalji email: https://app.rs/login?token=abc123
→ Token važi 10 min, jednokratan
Passkeys (WebAuthn)
  • Biometrika (FaceID, otisak)
  • Hardverski ključevi (YubiKey)
  • Nema lozinki!

Primer: NextAuth.js + Passkeys

// pages/api/auth/[...nextauth].ts
import NextAuth from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';
import { verifyPasskey } from 'webauthn';

export default NextAuth({
  providers: [
    CredentialsProvider({
      
// role: admin, editor, viewer
if (user.role === 'admin') allow('/admin');
Primer: Middleware u Next.js
// middleware.ts
import { NextResponse } from 'next/server';

export function middleware(req) {
  const token = req.cookies.get('auth');
  const user = verifyJWT(token);
  
  if (req.nextUrl.pathname.startsWith('/admin') && user.role !== 'admin') {
    return NextResponse.redirect(new URL('/login', req.url));
  }
  
  return NextResponse.next();
}
ABAC (Attribute-Based Access Control)
// Pravila:
if (user.department === 'HR' && resource.type === 'salary') allow;

Fleksibilnije, ali kompleksnije.

6. Bezbednost u mikroservisima

Izazovi:

  • JWT mora biti proveren u svakom servisu
  • Nema centralne sesije

Rešenja:

Rešenje Kako
API Gateway Proveri JWT pre rutiranja
Service Mesh (Istio) mTLS + JWT validacija
Shared Secret HS256 potpis
RSA/ES256 Javni ključ u svim servisima
app/
├── login/page.tsx
├── dashboard/page.tsx
├── admin/
│   └── page.tsx
├── api/
│   └── auth/[...nextauth]/route.ts
app/api/auth/[…nextauth]/route.ts
import NextAuth from 'next-auth';
import CredentialsProvider from 'next-auth/providers/credentials';
import GoogleProvider from 'next-auth/providers/google';
import { PrismaAdapter } from '@next-auth/prisma-adapter';
import { prisma } from '@/lib/prisma';
import bcrypt from 'bcrypt';

const handler = NextAuth({
  adapter: PrismaAdapter(prisma),
  providers: [
    CredentialsProvider({
      name: 'Email',
      credentials: {
        email: { label: 'Email', type: 'email' },
        password: { label: 'Password', type: 'password' }
      },
      async authorize(credentials) {
        const user = await prisma.user.findUnique({ where: { email: credentials.email } });
        if (!user) return null;
        const match = await bcrypt.compare(credentials.password, user.passwordHash);
        if (match) return user;
        return null;
      }
    }),
    GoogleProvider({
      clientId: process.env.GOOGLE_ID,
      clientSecret: process.env.GOOGLE_SECRET
    })
  ],
  callbacks: {
    async jwt({ token, user }) {
      if (user) {
        token.role = user.role;
      }
      return token;
    },
    async session({ session, token }) {
      session.user.role = token.role;
      return session;
    }
  },
  pages: {
    signIn: '/login'
  }
});

export { handler as GET, handler as POST };

Zaštita rute (Server Component)

// app/admin/page.tsx
import { getServerSession } from 'next-auth';
import { authOptions } from '@/lib/auth';

export default async function AdminPage() {
  const session = await getServerSession(authOptions);
  
  if (!session || session.user.role !== 'admin') {
    return <div>403 - Zabranjeno</div>;
  }

  return <h1>Admin panel – dobrodošao, {session.user.name}!</h1>;
}
8. Best Practices
Pravilo Objašnjenje
HttpOnly + Secure cookie Za JWT – ne localStorage
Short-lived access token 15 min
Refresh token (HttpOnly) Dugovečan, rotira se
CORS ograničenja allowedOrigins: [‘https://app.rs’]
Rate limit na login 5 pokušaja / 10 min
2FA / MFA Za admin panele

Poređenje: Auth metode

Metoda Sigurnost UX Skalabilnost Kada koristiti
Lozinka + Sesija ★★ ★★★ ★★ Legacy
JWT + Cookie ★★★★ ★★★★ ★★★★★ Web app
OAuth2 / OIDC ★★★★★ ★★★★ ★★★★★ Socijalni login
Passkeys ★★★★★ ★★★★★ ★★★★ Budućnost
Moderni Auth stack
Frontend (Next.js) 
  ↓ (HttpOnly cookie)
API Gateway (JWT validacija)
  ↓
Mikroservisi (RBAC po claim-ovima)
  ↓
Baza (nikad plain lozinke)

Zlatno pravilo: „Nikad ne veruj klijentu. Uvek proveravaj na serveru.“

Šta dalje?

U devetom delu ulazimo u DevOps, CI/CD i observability:

  • GitOps
  • GitHub Actions
  • Prometheus + Grafana
  • OpenTelemetry

Tvoj izazov

  1. Implementiraj NextAuth.js sa:
    • Email/lozinka
    • Google login
    • RBAC middleware
  2. Dodaj Passkey podršku (koristi simplewebauthn)
  3. Uradi penetration test sa OWASP ZAP
  4. Komentariši ispod: „Koju auth metodu koristiš trenutno?“

Autor: Dušan Antonijević – saradnik ITNetwork.rs
Hvala na čitanju! Podeli tekst sa kolegama.

Banner

Banner

Možda će vam se svideti i