update backend/src/middleware/auth.ts
This commit is contained in:
parent
0797d85d78
commit
e1b3ea65ba
53
backend/src/middleware/auth.ts
Normal file
53
backend/src/middleware/auth.ts
Normal 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();
|
||||||
|
};
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user