v3.1.0APIs & Backend

Authentifizierung & Autorisierung

Schütze deine API-Endpunkte mit deklarativen Security-Decorators für JWT, OAuth2 und rollenbasierte Zugriffskontrolle.

@Auth Decorator

Der einfachste Weg, einen Endpunkt zu schützen. Velisch validiert automatisch das JWT-Token aus dem Authorization-Header.

@Auth
@GET("/api/profile")
fn getProfile(): User {
    // User wird automatisch aus dem JWT Token extrahiert
    return currentUser();
}

@Auth
@GET("/api/settings")
fn getSettings(): Settings {
    let user = currentUser();
    return db.find(Settings, user.id);
}

Rollenbasierte Zugriffskontrolle (RBAC)

Kombiniere @Auth mit @Role für feingranulare Berechtigungen:

@Auth
@Role("admin")
@GET("/api/admin/users")
fn getAdminUsers(): List<User> {
    return db.findAll(User);
}

@Auth
@Role("admin", "moderator")
@DELETE("/api/posts/:id")
fn deletePost(id: string): void {
    db.delete(Post, id);
}

@Auth
@Role("user")
@GET("/api/users/:id")
fn getUser(id: string): User {
    let user = currentUser();
    // User kann nur eigenes Profil sehen
    if (user.id != id && user.role != "admin") {
        throw HttpError.Forbidden("Kein Zugriff");
    }
    return db.find(User, id);
}

JWT Integration

Native Unterstützung für JWT-Token-Erstellung und -Validierung:

use auth

@POST("/api/login")
fn login(email: string, password: string): LoginResponse {
    let user = db.findBy(User, "email", email);
    
    if (!user || !verifyPassword(password, user.passwordHash)) {
        throw HttpError.Unauthorized("Ungültige Anmeldedaten");
    }
    
    let token = auth.jwt.sign({
        sub: user.id,
        role: user.role,
        exp: datetime.now() + duration("24h"),
    }, config.get("JWT_SECRET"));
    
    return LoginResponse {
        token: token,
        user: user,
    };
}

@POST("/api/register")
fn register(name: string, email: string, password: string): User {
    // Prüfen ob Email bereits existiert
    if (db.findBy(User, "email", email) != null) {
        throw HttpError.BadRequest("Email bereits registriert");
    }
    
    let user = User {
        id: utils.uuid(),
        name: name,
        email: email,
        passwordHash: hashPassword(password),
        role: "user",
        createdAt: datetime.now(),
    };
    
    return db.save(user);
}

@Auth
@POST("/api/refresh")
fn refreshToken(): string {
    let user = currentUser();
    return auth.jwt.sign({
        sub: user.id,
        role: user.role,
        exp: datetime.now() + duration("24h"),
    }, config.get("JWT_SECRET"));
}

OAuth2 & OpenID Connect

Moderne Authentifizierung mit externen Providern:

@OAuth2
@GET("/api/profile")
fn getOAuthProfile(): User {
    // Automatisch OAuth2-geschützt
    return currentUser();
}

@OAuth2(provider: "google")
@GET("/api/google/callback")
fn googleCallback(code: string): LoginResponse {
    let tokens = oauth.exchange(code);
    let userInfo = oauth.getUserInfo(tokens.access_token);
    
    // User erstellen oder aktualisieren
    let user = findOrCreateUser(userInfo);
    let jwt = createJwt(user);
    
    return LoginResponse { token: jwt, user: user };
}

@OIDC
@GET("/api/userinfo")
fn getUserInfo(): UserInfo {
    // OpenID Connect mit UserInfo Endpoint
    return fetchUserInfo();
}

@MFA
@POST("/api/sensitive-action")
fn performSensitiveAction(): ActionResult {
    // Multi-Factor Authentication erforderlich
    return executeAction();
}

API Key Authentication

@ApiKey
@GET("/api/v1/data")
fn getDataWithApiKey(): Data {
    // API Key wird aus X-API-Key Header validiert
    return fetchData();
}

@ApiKey(header: "Authorization", prefix: "Bearer ")
@GET("/api/v1/custom")
fn getDataWithCustomHeader(): Data {
    return fetchData();
}

// API Keys verwalten
@Auth
@Role("admin")
@POST("/api/keys")
fn createApiKey(name: string, permissions: List<string>): ApiKey {
    let key = ApiKey {
        id: utils.uuid(),
        key: utils.generateSecureKey(32),
        name: name,
        permissions: permissions,
        createdAt: datetime.now(),
    };
    return db.save(key);
}

Vault Integration

Sichere Verwaltung von Secrets über HashiCorp Vault:

use vault

@VaultSecret("secret/data/api", "api_key")
struct ApiConfig {
    apiKey: string,  // Wird automatisch aus Vault geladen
}

@GET("/api/external")
fn callExternalApi(): ExternalData {
    let config = vault.load(ApiConfig);
    return http.get("https://api.example.com", {
        headers: { "Authorization": "Bearer " + config.apiKey }
    });
}

// Database Credentials sicher aus Vault
fn connectDatabase(): Connection {
    let creds = vault.getDatabaseCredentials("postgres");
    return db.connect(creds.username, creds.password);
}

Security Features

JWT Tokens

Signierte Tokens mit konfigurierbarer Expiration

RBAC

Rollenbasierte Zugriffskontrolle mit @Role

OAuth2/OIDC

Integration mit Google, GitHub, Azure AD, etc.

MFA

Multi-Factor Authentication für sensible Aktionen

Best Practices

Secrets nie im Code

Nutze Environment Variables oder Vault

Short-lived Tokens

JWT Tokens sollten nach 1-24h ablaufen

Refresh Tokens

Für langlebige Sessions separate Refresh Tokens nutzen

Least Privilege

Gib Usern nur die minimal nötigen Berechtigungen