Eine umfassende Anleitung zur Implementierung von Authentifizierung und Autorisierung in der nodejs-server Anwendung.
Diese Dokumentation beschreibt Best Practices und Implementierungsstrategien für ein sicheres Authentication & Authorization System für das NestJS Backend und React Frontend.
Authentication verifiziert die Identität eines Benutzers - "Wer bist du?"
# Backend Dependencies installieren
npm install @nestjs/jwt @nestjs/passport passport passport-jwt bcrypt
npm install --save-dev @types/passport-jwt @types/bcryptVorteile:
- ✅ Stateless (keine Server-Sessions)
- ✅ Skalierbar für Microservices
- ✅ Cross-Domain Support
- ✅ Mobile App kompatibel
// src/auth/entities/user.entity.ts
@Entity()
export class User {
@PrimaryGeneratedColumn('uuid')
id: string;
@Column({ unique: true })
email: string;
@Column()
password: string; // Gehashed mit bcrypt
@Column({ default: 'user' })
role: string; // 'admin', 'user', 'moderator'
@CreateDateColumn()
createdAt: Date;
@UpdateDateColumn()
updatedAt: Date;
}src/auth/
├── auth.controller.ts # Login, Register, Refresh Endpoints
├── auth.module.ts # Auth Module Configuration
├── auth.service.ts # Business Logic
├── guards/
│ ├── jwt-auth.guard.ts # JWT Route Protection
│ └── roles.guard.ts # Role-based Access Control
├── strategies/
│ └── jwt.strategy.ts # JWT Validation Strategy
├── dto/
│ ├── login.dto.ts # Login Request DTO
│ ├── register.dto.ts # Registration DTO
│ └── auth-response.dto.ts # Auth Response DTO
└── entities/
└── user.entity.ts # User Database Entity
| Endpoint | Method | Beschreibung |
|---|---|---|
/auth/register |
POST | Benutzer registrieren |
/auth/login |
POST | Benutzer anmelden |
/auth/refresh |
POST | Token erneuern |
/auth/logout |
POST | Benutzer abmelden |
/auth/profile |
GET | Benutzerprofil abrufen |
Authorization bestimmt, was ein authentifizierter Benutzer tun darf - "Was darfst du?"
export enum UserRole {
ADMIN = 'admin',
MODERATOR = 'moderator',
USER = 'user'
}
export enum Permission {
// Project Permissions
CREATE_PROJECT = 'create:project',
READ_PROJECT = 'read:project',
UPDATE_PROJECT = 'update:project',
DELETE_PROJECT = 'delete:project',
// Issue Permissions
CREATE_ISSUE = 'create:issue',
READ_ISSUE = 'read:issue',
UPDATE_ISSUE = 'update:issue',
DELETE_ISSUE = 'delete:issue',
// Admin Permissions
MANAGE_USERS = 'manage:users'
}// guards/roles.guard.ts
@Injectable()
export class RolesGuard implements CanActivate {
constructor(private reflector: Reflector) {}
canActivate(context: ExecutionContext): boolean {
const requiredRoles = this.reflector.getAllAndOverride<UserRole[]>('roles', [
context.getHandler(),
context.getClass(),
]);
if (!requiredRoles) return true;
const { user } = context.switchToHttp().getRequest();
return requiredRoles.some((role) => user.role === role);
}
}// decorators/roles.decorator.ts
export const Roles = (...roles: UserRole[]) => SetMetadata('roles', roles);
// Controller Usage
@Controller('projects')
@UseGuards(JwtAuthGuard, RolesGuard)
export class ProjectsController {
@Get()
@Roles(UserRole.USER, UserRole.ADMIN)
findAll() {
// Alle Benutzer und Admins können Projekte lesen
}
@Delete(':id')
@Roles(UserRole.ADMIN)
delete(@Param('id') id: string) {
// Nur Admins können Projekte löschen
}
}- User Entity & Migration erstellen
- Auth Module implementieren
- JWT Strategy konfigurieren
- Guards für Route Protection
- Password Hashing mit bcrypt
- Auth Context/Store implementieren
- Login/Register Komponenten
- Token Management (localStorage/Cookie)
- Protected Routes
- Automatic Token Refresh
- Role-based Guards
- Permission System
- UI Conditional Rendering
- Admin Dashboard
// contexts/AuthContext.tsx
interface AuthContextType {
user: User | null;
token: string | null;
login: (email: string, password: string) => Promise<void>;
register: (userData: RegisterData) => Promise<void>;
logout: () => void;
isAuthenticated: boolean;
}
export const AuthProvider: React.FC<{ children: ReactNode }> = ({ children }) => {
const [user, setUser] = useState<User | null>(null);
const [token, setToken] = useState<string | null>(
localStorage.getItem('token')
);
// Implementation...
};// components/ProtectedRoute.tsx
interface ProtectedRouteProps {
children: ReactNode;
requiredRole?: UserRole;
}
export const ProtectedRoute: React.FC<ProtectedRouteProps> = ({
children,
requiredRole
}) => {
const { user, isAuthenticated } = useAuth();
if (!isAuthenticated) {
return <Navigate to="/login" />;
}
if (requiredRole && user?.role !== requiredRole) {
return <Navigate to="/unauthorized" />;
}
return <>{children}</>;
};- ✅ Password Hashing: bcrypt mit Salt Rounds ≥ 12
- ✅ JWT Security: Kurze Access Token (15min) + Refresh Token
- ✅ Input Validation: Class-validator für alle DTOs
- ✅ Rate Limiting: Schutz vor Brute Force Attacken
- ✅ CORS Configuration: Restriktive CORS für Production
- ✅ Helmet.js: Security Headers
- ✅ Environment Variables: Secrets in .env Files
- ✅ Secure Storage: HttpOnly Cookies für Tokens (Production)
- ✅ Token Expiry: Automatic Token Refresh
- ✅ Input Sanitization: XSS Protection
- ✅ HTTPS Only: Sichere Datenübertragung
- ✅ CSP Headers: Content Security Policy
// Events to log
enum AuthEvent {
USER_REGISTERED = 'user.registered',
USER_LOGIN_SUCCESS = 'user.login.success',
USER_LOGIN_FAILED = 'user.login.failed',
TOKEN_REFRESHED = 'token.refreshed',
USER_LOGOUT = 'user.logout',
UNAUTHORIZED_ACCESS = 'access.unauthorized'
}- 📈 Login Success Rate
- 📈 Failed Login Attempts
- 📈 Token Refresh Frequency
- 📈 Session Duration
- 📈 Role Distribution
// auth.service.spec.ts
describe('AuthService', () => {
it('should hash password correctly', async () => {
const password = 'plainPassword';
const hashed = await authService.hashPassword(password);
expect(await bcrypt.compare(password, hashed)).toBe(true);
});
it('should generate valid JWT token', async () => {
const user = { id: '1', email: 'test@example.com', role: 'user' };
const token = await authService.generateToken(user);
expect(jwt.verify(token, process.env.JWT_SECRET)).toBeTruthy();
});
});// AuthContext.test.tsx
describe('AuthContext', () => {
it('should login user successfully', async () => {
const { result } = renderHook(() => useAuth(), {
wrapper: AuthProvider,
});
await act(async () => {
await result.current.login('test@example.com', 'password');
});
expect(result.current.isAuthenticated).toBe(true);
});
});- User Table hinzufügen ohne bestehende Daten zu beeinträchtigen
- Optional Authentication - Zunächst als Feature Flag
- Graduelle Migration - Route für Route absichern
- Backward Compatibility - Während Übergangsphase
- Database Migration: User Schema hinzufügen
- Environment Variables: JWT_SECRET, bcrypt Rounds
- Redis/Session Store: Für Token Blacklisting (optional)
- Load Balancer: Session Affinity nicht erforderlich (JWT)
- NestJS Authentication
- JWT.io - JWT Token Debugger
- OWASP Auth Guide
Dokumentation erstellt am: 6. September 2025
Status: Implementierungsbereit
Nächste Schritte: Phase 1 Backend Implementation