Initial commit: IHK Ausbildung materials

This commit is contained in:
2026-03-13 11:46:08 +01:00
commit eb4a13ef7c
67 changed files with 11361 additions and 0 deletions

View File

@@ -0,0 +1,42 @@
# Lernfeld 6: Webanwendungen entwickeln
## Übersicht
Dieses Lernfeld behandelt die Entwicklung von Webanwendungen.
## Themen
| Nr. | Thema | Beschreibung |
| --- | --- | --- |
| 6.1 | [[LF6-01-Web-Grundlagen]] | HTTP, HTML, CSS |
| 6.2 | [[LF6-02-Frontend]] | JavaScript, Frameworks |
| 6.3 | [[LF6-03-Backend]] | Server, APIs, Datenbanken |
| 6.4 | [[LF6-04-Sicherheit-Web]] | XSS, CSRF, SQL Injection |
## Lernziele
- Webanwendungen entwickeln
- Frontend und Backend verbinden
- Sicherheitslücken erkennen und vermeiden
## Voraussetzungen
- LF3: Datenbanken
- LF4: IT-Sicherheit
- LF5: Analyse und Design
## Prüfungsrelevanz
- Teil 2 Abschlussprüfung (praktisch)
---
## Querverweise
- [[LF5-04-Testverfahren|Zurück: Testverfahren]]
- [[LF9-Netzwerke-Dienste|Nächstes Lernfeld: Netzwerke]]
- [[Wissen/Wirtschafts-Sozialkunde/WISO-Zusammenfassung|WISO: E-Commerce]]
---
*Stand: 2024*

View File

@@ -0,0 +1,225 @@
# 6.1 Web-Grundlagen
## Internet und WWW
### Grundbegriffe
```
Internet - Netzwerk der Netzwerke
WWW (World Wide Web) - Dienst im Internet
```
### Funktionsweise
```
Client-Server-Modell
┌─────────┐ ┌─────────┐
│ Browser │ ───────►│ Server │
│ (Client)│ ◄───────│ │
└─────────┘ └─────────┘
```
---
## HTTP - Hypertext Transfer Protocol
### HTTP-Ablauf
```
HTTP - Kommunikation
1. Client sendet Request
2. Server verarbeitet
3. Server sendet Response
```
### HTTP-Methoden
| Methode | Beschreibung | idempotent |
|---------|-------------|------------|
| **GET** | Daten abrufen | Ja |
| **POST** | Daten senden | Nein |
| **PUT** | Daten ersetzen | Ja |
| **PATCH** | Daten teilweise ändern | Nein |
| **DELETE** | Daten löschen | Ja |
### HTTP-Statuscodes
| Code | Bedeutung | Beispiel |
|------|-----------|----------|
| **200** | OK | Erfolgreich |
| **201** | Created | Erstellt |
| **301** | Moved Permanently | Umleitung |
| **400** | Bad Request | Fehlerhafte Anfrage |
| **401** | Unauthorized | Nicht angemeldet |
| **403** | Forbidden | Keine Berechtigung |
| **404** | Not Found | Nicht gefunden |
| **500** | Internal Server Error | Serverfehler |
### HTTPS
```
HTTPS = HTTP + TLS-Verschlüsselung
Vorteile:
├── Vertraulichkeit
├── Integrität
└── Authentifizierung
```
---
## HTML - HyperText Markup Language
### Grundstruktur
```html
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Titel</title>
</head>
<body>
<!-- Inhalt -->
</body>
</html>
```
### HTML-Elemente
| Element | Bedeutung |
|---------|----------|
| `<h1>` bis `<h6>` | Überschriften |
| `<p>` | Absatz |
| `<a>` | Link |
| `<img>` | Bild |
| `<ul>`, `<ol>` | Liste |
| `<table>` | Tabelle |
| `<form>` | Formular |
| `<div>`, `<span>` | Container |
### Semantisches HTML
```html
<header>Kopfbereich</header>
<nav>Navigation</nav>
<main>
<article>
<section>Inhalt</section>
</article>
<aside>Seitenleiste</aside>
</main>
<footer>Fußbereich</footer>
```
---
## CSS - Cascading Style Sheets
### Einbindung
```html
<!-- Extern -->
<link rel="stylesheet" href="style.css">
<!-- Intern -->
<style>
body { background: white; }
</style>
<!-- Inline -->
<p style="color: red;">Text</p>
```
### CSS-Selektoren
```css
/* Element */
p { color: blue; }
/* Klasse */
.klasse { font-size: 16px; }
/* ID */
#id { background: gray; }
/* Attribut */
[type="text"] { border: 1px solid; }
/* Pseudoklasse */
:hover { cursor: pointer; }
/* Nachfahre */
div p { margin: 10px; }
```
### Flexbox
```css
.container {
display: flex;
justify-content: space-between;
align-items: center;
}
```
### Grid
```css
.grid {
display: grid;
grid-template-columns: repeat(3, 1fr);
gap: 20px;
}
```
---
## Responsive Design
### Viewport
```html
<meta name="viewport"
content="width=device-width, initial-scale=1.0">
```
### Media Queries
```css
/* Mobile zuerst */
.container {
width: 100%;
}
@media (min-width: 768px) {
.container {
width: 750px;
}
}
@media (min-width: 1024px) {
.container {
width: 970px;
}
}
```
### Breakpoints
| Gerät | Breite |
|-------|--------|
| Mobile | < 768px |
| Tablet | 768px - 1023px |
| Desktop | >= 1024px |
---
## Querverweise
- [[LF6-02-Frontend|Nächstes Thema: Frontend-Entwicklung]]
- [[LF4-02-Schutzmassnahmen|IT-Sicherheit: HTTPS]]
---
*Stand: 2024*

View File

@@ -0,0 +1,268 @@
# 6.2 Frontend-Entwicklung
## JavaScript
### Grundlagen
```javascript
// Variablen
let name = "Max"; // veränderbar
const alter = 25; // konstant
// Datentypen
let text = "Hallo"; // String
letzahl = 42; // Number
let wahr = true; // Boolean
let array = [1, 2, 3]; // Array
let objekt = { // Object
name: "Max",
alter: 25
};
```
### Kontrollstrukturen
```javascript
// Bedingung
if (alter >= 18) {
console.log("Volljährig");
} else {
console.log("Minderjährig");
}
// Switch
switch (tag) {
case "Mo":
case "Di":
console.log("Arbeitstag");
break;
default:
console.log("Wochenende");
}
// Schleifen
for (let i = 0; i < 5; i++) {
console.log(i);
}
array.forEach(item => {
console.log(item);
});
```
### Funktionen
```javascript
// Funktionsdeklaration
function gruss(name) {
return "Hallo " + name;
}
// Arrow Function
const gruss = (name) => "Hallo " + name;
// Mit Standardwert
function gruss(name = "Gast") {
return "Hallo " + name;
}
```
---
## DOM - Document Object Model
### Element auswählen
```javascript
// Nach ID
const element = document.getElementById("meine-id");
// Nach Klasse
const elemente = document.getElementsByClassName("klasse");
// Nach Selektor
const element = document.querySelector(".klasse");
const elemente = document.querySelectorAll("p");
```
### Inhalt ändern
```javascript
// Text ändern
element.textContent = "Neuer Text";
// HTML ändern
element.innerHTML = "<strong>Fett</strong>";
// Attribute
element.setAttribute("class", "neu");
element.getAttribute("href");
```
### Events
```javascript
// Event Listener
element.addEventListener("click", function() {
console.log("Geklickt!");
});
// Arrow Function
element.addEventListener("click", () => {
alert("Geklickt!");
});
```
---
## Formulare
### HTML-Formular
```html
<form id="login-form">
<label for="email">E-Mail:</label>
<input type="email" id="email" name="email" required>
<label for="password">Passwort:</label>
<input type="password" id="password" name="password" required>
<button type="submit">Anmelden</button>
</form>
```
### Formulardaten auslesen
```javascript
const formular = document.getElementById("login-form");
formular.addEventListener("submit", function(e) {
e.preventDefault(); // Verhindert Seitenreload
const formData = new FormData(formular);
const daten = Object.fromEntries(formData);
console.log(daten);
// { email: "...", password: "..." }
});
```
---
## Frameworks
### React
```jsx
import React, { useState } from 'react';
function Counter() {
const [count, setCount] = useState(0);
return (
<div>
<p>Zähler: {count}</p>
<button onClick={() => setCount(count + 1)}>
Erhöhen
</button>
</div>
);
}
```
### Vue
```html
<script setup>
import { ref } from 'vue';
const count = ref(0);
</script>
<template>
<p>Zähler: {{ count }}</p>
<button @click="count++">Erhöhen</button>
</template>
```
### Vergleich
| Framework | Typ |特点 |
|-----------|-----|-----|
| React | Library | Flexibel, große Community |
| Vue | Framework | Einfach zu lernen |
| Angular | Framework | Enterprise, TypeScript |
---
## Asynchrone Programmierung
### Promises
```javascript
// Promise erstellen
const promise = new Promise((resolve, reject) => {
// Async Operation
if (erfolg) {
resolve("Erfolg!");
} else {
reject("Fehler!");
}
});
// Nutzen
promise
.then(ergebnis => console.log(ergebnis))
.catch(fehler => console.error(fehler));
```
### Async/Await
```javascript
async function datenLaden() {
try {
const response = await fetch('/api/daten');
const daten = await response.json();
console.log(daten);
} catch (error) {
console.error("Fehler:", error);
}
}
```
---
## Fetch API
```javascript
// GET
fetch('/api/benutzer')
.then(response => response.json())
.then(data => console.log(data));
// POST
fetch('/api/benutzer', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: "Max",
email: "max@example.com"
})
})
.then(response => response.json())
.then(data => console.log(data));
```
---
## Querverweise
- [[LF6-01-Web-Grundlagen|Zurück: Web-Grundlagen]]
- [[LF6-03-Backend|Nächstes Thema: Backend-Entwicklung]]
- [[LF6-04-Sicherheit-Web|Web-Sicherheit]]
---
*Stand: 2024*

View File

@@ -0,0 +1,272 @@
# 6.3 Backend-Entwicklung
## Server-Grundlagen
### Client-Server-Architektur
```
Webanwendung - Architektur
┌─────────────┐ HTTP ┌─────────────┐
│ Browser │ ◄──────────────►│ Server │
│ (Frontend) │ │ (Backend) │
└─────────────┘ └──────┬──────┘
┌─────┴─────┐
│ Datenbank │
└───────────┘
```
---
## Node.js
### Grundlagen
```javascript
// Einfacher Server
const http = require('http');
const server = http.createServer((req, res) => {
res.writeHead(200, { 'Content-Type': 'text/html' });
res.end('<h1>Hallo Welt!</h1>');
});
server.listen(3000, () => {
console.log('Server läuft auf Port 3000');
});
```
### Express.js
```javascript
const express = require('express');
const app = express();
// Middleware
app.use(express.json());
// GET-Route
app.get('/api/benutzer', (req, res) => {
res.json([
{ id: 1, name: 'Max' },
{ id: 2, name: 'Anna' }
]);
});
// POST-Route
app.post('/api/benutzer', (req, res) => {
const neuerBenutzer = req.body;
// Speichern...
res.status(201).json(neuerBenutzer);
});
app.listen(3000);
```
---
## REST-API
### REST-Prinzipien
```
REST - Grundsätze
├── Ressourcen-orientiert (Nomen)
├── Stateless (keine Session)
├── Einheitliche Schnittstelle
├── Client-Server-Trennung
└── Cache-fähig
```
### HTTP-Methoden
| Methode | CRUD | Beschreibung |
|---------|-----|-------------|
| GET | Read | Daten abrufen |
| POST | Create | Daten erstellen |
| PUT | Update | Daten vollständig ersetzen |
| PATCH | Update | Daten teilweise ändern |
| DELETE | Delete | Daten löschen |
### API-Endpunkte
```
Beispiel: Benutzer-Ressource
GET /api/benutzer → Alle Benutzer
GET /api/benutzer/:id → Ein Benutzer
POST /api/benutzer → Benutzer erstellen
PUT /api/benutzer/:id → Benutzer ersetzen
PATCH /api/benutzer/:id → Benutzer ändern
DELETE /api/benutzer/:id → Benutzer löschen
```
### Response-Format
```json
// Erfolgreich (200 OK)
{
"status": "success",
"data": {
"id": 1,
"name": "Max"
}
}
// Erfolg (201 Created)
{
"status": "success",
"message": "Benutzer erstellt",
"data": {
"id": 2
}
}
// Fehler (400 Bad Request)
{
"status": "error",
"message": "Ungültige E-Mail-Adresse"
}
```
---
## Datenbank-Zugriff
### MySQL mit Node.js
```javascript
const mysql = require('mysql2/promise');
async function main() {
const connection = await mysql.createConnection({
host: 'localhost',
user: 'root',
password: 'passwort',
database: 'webshop'
});
// Daten abfragen
const [rows] = await connection.execute(
'SELECT * FROM benutzer WHERE id = ?',
[1]
);
console.log(rows);
await connection.end();
}
main();
```
### MongoDB mit Node.js
```javascript
const mongoose = require('mongoose');
// Verbindung
mongoose.connect('mongodb://localhost:27017/webshop');
// Schema
const benutzerSchema = new mongoose.Schema({
name: String,
email: { type: String, unique: true },
alter: Number
});
const Benutzer = mongoose.model('Benutzer', benutzerSchema);
// Daten speichern
const neuerBenutzer = new Benutzer({
name: 'Max',
email: 'max@example.com'
});
await neuerBenutzer.save();
```
---
## Session und Authentifizierung
### JWT (JSON Web Token)
```javascript
const jwt = require('jsonwebtoken');
// Token erstellen
function createToken(user) {
return jwt.sign(
{ id: user.id, email: user.email },
'geheimer-schluessel',
{ expiresIn: '24h' }
);
}
// Token prüfen
function verifyToken(token) {
try {
return jwt.verify(token, 'geheimer-schluessel');
} catch (err) {
return null;
}
}
// Middleware
function authenticate(req, res, next) {
const token = req.headers.authorization?.split(' ')[1];
const decoded = verifyToken(token);
if (!decoded) {
return res.status(401).json({ error: 'Nicht autorisiert' });
}
req.user = decoded;
next();
}
```
### Passwort-Hashing
```javascript
const bcrypt = require('bcrypt');
// Passwort hashen
async function hashPassword(password) {
const salt = await bcrypt.genSalt(10);
return await bcrypt.hash(password, salt);
}
// Passwort prüfen
async function checkPassword(password, hash) {
return await bcrypt.compare(password, hash);
}
```
---
## RESTful Best Practices
### Tipps
```
API-Design - Empfehlungen
├── Versionierung: /api/v1/...
├── Plural: /benutzer nicht /benutzer
├── Filter: /benutzer?alter=25
├── Sortierung: /benutzer?sort=name
├── Paginierung: /benutzer?page=1&limit=10
├── Fehlercodes: HTTP-Statuscodes nutzen
└── Dokumentation: OpenAPI/Swagger
```
---
## Querverweise
- [[LF6-02-Frontend|Zurück: Frontend-Entwicklung]]
- [[LF6-04-Sicherheit-Web|Nächstes Thema: Web-Sicherheit]]
- [[LF3-Datenbanken|Datenbanken]]
---
*Stand: 2024*

View File

@@ -0,0 +1,257 @@
# 6.4 Web-Sicherheit
## OWASP Top 10
### Die wichtigsten Sicherheitsrisiken
```
OWASP Top 10 (2021)
├── A01: Broken Access Control
├── A02: Cryptographic Failures
├── A03: Injection
├── A04: Insecure Design
├── A05: Security Misconfiguration
├── A06: Vulnerable Components
├── A07: Authentification Failures
├── A08: Software and Data Integrity Failures
├── A09: Security Logging Failures
└── A10: Server-Side Request Forgery
```
---
## Injection
### SQL Injection
**Problem:** Benutzereingaben werden direkt in SQL-Abfragen eingebaut.
```sql
-- Gefährlich
SELECT * FROM benutzer WHERE name = '" + name + "'
-- Bei name = "' OR '1'='1"
SELECT * FROM benutzer WHERE name = '' OR '1'='1'
-- → Alle Benutzer werden zurückgegeben!
```
**Schutz: Prepared Statements**
```javascript
// Gefährlich
db.query("SELECT * FROM users WHERE name = '" + name + "'");
// Sicher - Parameterized Query
db.query("SELECT * FROM users WHERE name = ?", [name]);
```
### XSS (Cross-Site Scripting)
**Problem:** Schadcode wird in Webseiten eingeschleust.
```html
<!-- Gefährlich: Benutzereingabe direkt ausgeben -->
<div>{{ benutzereingabe }}</div>
<!-- Bei eingabe = <script>alert('XSS')</script> -->
```
**Schutz: Output Encoding**
```javascript
// HTML-Escaping
function escapeHtml(text) {
const map = {
'&': '&amp;',
'<': '&lt;',
'>': '&gt;',
'"': '&quot;',
"'": '&#039;'
};
return text.replace(/[&<>"']/g, m => map[m]);
}
// React macht das automatisch
<div>{benutzereingabe}</div>
```
### Content Security Policy (CSP)
```http
Content-Security-Policy: default-src 'self'; script-src 'self'
```
---
## CSRF (Cross-Site Request Forgery)
### Das Problem
```
CSRF-Angriff
1. Opfer ist eingeloggt bei bank.com
2. Opfer besucht bösartige Seite
3. Bösartige Seite sendet Request an bank.com
4. Browser sendet automatisch Session-Cookie
5. Überweisung wird ausgeführt
```
### Schutz: CSRF-Token
```javascript
// Server: Token generieren
app.get('/form', (req, res) => {
const csrfToken = crypto.randomBytes(32).toString('hex');
req.session.csrfToken = csrfToken;
res.render('form', { csrfToken });
});
// Server: Token prüfen
app.post('/transfer', (req, res) => {
if (req.body.csrfToken !== req.session.csrfToken) {
return res.status(403).send('CSRF-Angriff erkannt');
}
// Weiter mit Überweisung...
});
```
---
## Authentifizierung
### Unsichere Praktiken
```
Vermeiden
├── Passwörter im Klartext speichern
├── Schwache Passwörter erlauben
├── Keine Zwei-Faktor-Authentifizierung
├── Session-IDs in URL
└── Unbegrenzte Login-Versuche
```
### Sichere Authentifizierung
```javascript
// 1. Passwörter hashen
const hash = await bcrypt.hash(passwort, 12);
// 2. Rate Limiting
const rateLimit = require('express-rate-limit');
app.use('/login', rateLimit({
windowMs: 15 * 60 * 1000,
max: 5 // 5 Versuche
}));
// 3. Sichere Session
app.use(session({
secret: 'geheimer-schluessel',
httpOnly: true,
secure: true, // HTTPS
sameSite: 'strict'
}));
```
---
## Sicherheits-Header
### Wichtige Header
```http
# HSTS - HTTPS erzwingen
Strict-Transport-Security: max-age=31536000; includeSubDomains
# X-Content-Type-Options
X-Content-Type-Options: nosniff
# X-Frame-Options - Clickjacking
X-Frame-Options: DENY
# Content Security Policy
Content-Security-Policy: default-src 'self'
# Referrer Policy
Referrer-Policy: strict-origin-when-cross-origin
```
### Implementierung in Express
```javascript
const helmet = require('helmet');
app.use(helmet());
```
---
## Eingabevalidierung
### Grundprinzip
```
Validierung - Regeln
├── Nie Benutzereingaben vertrauen
├── Client-seitige Validierung reicht nicht
├── Whitelist statt Blacklist
├── Länge und Format prüfen
└── Alle Eingaben validieren
```
### Validierungsbeispiel
```javascript
const Joi = require('joi');
const benutzerSchema = Joi.object({
name: Joi.string()
.alphanum()
.min(3)
.max(30)
.required(),
email: Joi.string()
.email()
.required(),
alter: Joi.number()
.integer()
.min(18)
.max(150)
});
// Validierung
const { error, value } = benutzerSchema.validate(req.body);
if (error) {
return res.status(400).json({ error: error.details });
}
```
---
## Checkliste Web-Sicherheit
```
Sicherheits-Checkliste
□ HTTPS erzwingen
□ Sicherheits-Header setzen
□ SQL Injection verhindern (Prepared Statements)
□ XSS verhindern (Escaping)
□ CSRF-Token verwenden
□ Passwörter hashen (bcrypt)
□ Rate Limiting
□ Eingaben validieren
□ Fehlermeldungen nicht zu detailliert
□ Regelmäßige Updates
□ Sicherheitstests durchführen
```
---
## Querverweise
- [[LF6-03-Backend|Zurück: Backend-Entwicklung]]
- [[LF4-IT-Sicherheit|IT-Sicherheit allgemein]]
- [[LF3-05-Datenbankmanagement|Datenbank: SQL Injection]]
---
*Stand: 2024*