update backend/src/middleware/auth.ts

This commit is contained in:
Giuseppe Lombardo 2026-08-12 17:45:54 +00:00
parent 0797d85d78
commit e1b3ea65ba

View File

@ -0,0 +1,53 @@
import { Request, Response, NextFunction } from 'express';
import jwt from 'jsonwebtoken';
// In Produktion MUSS JWT_SECRET über eine Server-Umgebungsvariable gesetzt sein
// (siehe .env auf dem VPS). Der Fallback ist nur für die lokale Entwicklung.
export const JWT_SECRET = process.env.JWT_SECRET || 'dev-secret-change-me-in-production';
export const JWT_EXPIRES_IN = '30d';
export interface AuthUser {
id: string;
email: string;
role: string;
}
export interface AuthedRequest extends Request {
user?: AuthUser;
}
export function signAuthToken(user: AuthUser): string {
return jwt.sign({ sub: user.id, email: user.email, role: user.role }, JWT_SECRET, {
expiresIn: JWT_EXPIRES_IN,
});
}
/** Erfordert einen gültigen Bearer-JWT im Authorization-Header. */
export function requireAuth(req: AuthedRequest, res: Response, next: NextFunction) {
const header = req.headers.authorization;
if (!header || !header.startsWith('Bearer ')) {
return res.status(401).json({ error: 'Nicht authentifiziert' });
}
const token = header.slice('Bearer '.length);
try {
const payload = jwt.verify(token, JWT_SECRET) as jwt.JwtPayload;
req.user = {
id: String(payload.sub),
email: String(payload.email),
role: String(payload.role),
};
next();
} catch {
return res.status(401).json({ error: 'Token ungültig oder abgelaufen' });
}
}
/** Erfordert zusätzlich eine der angegebenen Rollen (nach requireAuth einsetzen). */
export function requireRole(...roles: string[]) {
return (req: AuthedRequest, res: Response, next: NextFunction) => {
if (!req.user || !roles.includes(req.user.role)) {
return res.status(403).json({ error: 'Keine Berechtigung für diese Aktion' });
}
next();
};
}