Advertisement
  1. Code
  2. PHP

Integration der Zwei-Faktor-Authentifizierung in CodeIgniter

Scroll to top
Read Time: 14 min

German (Deutsch) translation by Katharina Grigorovich-Nevolina (you can also view the original English article)

Angesichts der jüngsten Reihe hochkarätiger Einbrüche (Hacks) bei Sony und anderen Unternehmen ist es an der Zeit, einen zweiten Blick auf die Sicherheit Ihrer Website zu werfen. Die Zwei-Faktor-Authentifizierung ist ein Schritt in die richtige Richtung, um Ihre Website vor Angreifern zu schützen. In diesem Tutorial sehen wir uns an, wie dies in unserer CodeIgniter-Anwendung implementiert wird.


Was ist eine Zwei-Faktor-Authentifizierung?

Bei der Zwei-Faktor-Authentifizierung müssen Benutzer etwas verwenden, das sie kennen, z. B. einen Benutzernamen und ein Kennwort, und etwas, über das sie sich wie ein Telefon anmelden können.

In letzter Zeit haben Unternehmen wie Google und Facebook eine Zwei-Faktor-Authentifizierung für ihre Benutzer eingeführt. Andere Dienste wie MailChimp verwenden alternative Formen der Zwei-Faktor-Authentifizierung, um Angreifer zu vereiteln. Was genau ist die Zwei-Faktor-Authentifizierung?

Die Zwei-Faktor-Authentifizierung ist eine Möglichkeit, Ihre Identität anhand Ihres Benutzernamens und Passworts sowie eines physischen Geräts zu beweisen, das Sie mit sich führen können.

Duo supports push notificationsDuo supports push notificationsDuo supports push notifications Die mobile Anwendung von Duo unterstützt Push-Benachrichtigungen zur Authentifizierung!

Dies macht es für Gauner viel schwieriger, Ihre Identität zu stehlen, da sie Zugriff auf Ihr Telefon oder Hardware-Token benötigen - nicht nur auf Ihre Anmeldeinformationen.

Zum Glück bietet Duo Security einen kostenlosen Zwei-Faktor-Service, der sich ideal für alle eignet, die ihre Website schützen möchten.

Duo ist nicht nur kostenlos, sondern auch voller Funktionen. Sie können sich auf verschiedene Arten authentifizieren, darunter:

  • Telefonanrufauthentifizierung
  • SMS-basierte Token
  • Token-Generator für mobile Apps
  • Push-basierte Authentifizierung
  • Hardware-Token können erworben werden

Schritt 1: Setup

CodeIgniter einrichten

Wenn Sie noch nie mit CodeIgniter gearbeitet haben, empfehle ich Ihnen dringend, zuerst die CodeIgniter From Scratch-Reihe zu lesen.

Dieses Tutorial baut auf dem Tutorial zur Einfachen Authentifizierung mit CodeIgniter auf. Dieses Tutorial ist für Sie viel einfacher zu verstehen, wenn Sie das vorherige Tutorial abgeschlossen haben, bevor Sie fortfahren. Wir werden die Dateien aus diesem Tutorial als Ausgangspunkt verwenden.

Bitte stellen Sie sicher, dass in Ihrer config/autoload.php die folgenden Helfer geladen sind.

1
$autoload['helper'] = array('url', 'form');

Ein Konto erstellen

Gehen Sie zu Duo Security und eröffnen Sie ein Konto.

Sie bieten einen kostenlosen Plan für Open Source-Projekte und für Websites mit weniger als 10 Duo-Benutzern (Ein Duo-Benutzer ist jemand, der die Zwei-Faktor-Authentifizierung zum Anmelden verwendet).

Erstellen Sie eine Integration

Nach der Registrierung müssen Sie sich bei Duo anmelden und eine Integration erstellen. Klicken Sie nach dem Anmelden im Seitenbereich auf Integrationen, um die Integrationsseite aufzurufen. Klicken Sie dort auf die Schaltfläche "Neue Integration".

Stellen Sie sicher, dass die von Ihnen erstellte Integration eine Web SDK-Integration ist. Auf diese Weise können Sie die PHP-API mit CodeIgniter verwenden.

Der Integrationsname wird nur auf der Duo-Website verwendet. Dies ist nur eine Möglichkeit für Sie, Ihre Integration zu identifizieren. Duo hat eine Anleitung für die ersten Schritte, in der erklärt wird, wie eine Integration eingerichtet wird.

Laden Sie das Web SDK herunter

Zusätzlich zum Einrichten einer Integration müssen Sie das Web SDK herunterladen.

Es gibt zwei Teile des SDK, die wir benötigen: Eine PHP-Datei (duo_web.php) und eine JavaScript-Datei. Bitte beachten Sie, dass das JavaScript eine jQuery-Abhängigkeit aufweist und das mitgelieferte JavaScript mit jQuery geliefert wird.

Wir werden das mitgelieferte JavaScript verwenden. Beachten Sie jedoch, dass jQuery vor dem von Duo bereitgestellten JavaScript geladen werden muss, wenn dies nicht der Fall ist. Weitere Informationen zum Web SDK und seiner Funktionsweise finden Sie in der Dokumentation unter http://www.duosecurity.com/docs/duoweb


Schritt 2: Änderungen für die Sicherheit

Nach Abschluss des Tutorials zur Einfachen Authentifizierung mit CodeIgniter sollten Sie über ein grundlegendes Anmeldesystem verfügen.

Besser Hashing

In einem ersten Schritt fügen wir der Datenbank eine starke Hashing-Funktion hinzu. Openwall hat eine schöne PHP-Hashing-Bibliothek, die bcrypt implementiert. Die neueste Version von phpass ist zum Zeitpunkt dieses Artikels 0.3.

Laden Sie phpass von der Website herunter: http://openwall.com/phpass/. Nachdem Sie den Ordner heruntergeladen und die Archivierung aufgehoben haben, müssen Sie ihn in Ihrem Bibliotheksordner ablegen.

Wir müssen jetzt unsere eigene Bibliotheksdatei als Schnittstelle zu phpass erstellen. Erstellen Sie eine neue Bibliotheksdatei mit dem Namen password.php. Unsere Bibliothek wird zwei Funktionen haben:

  • eine Hash-Funktion zum erneuten Aufbereiten der alten Passwörter
  • eine check_password-Funktion zum Vergleichen von Hashes mit Klartext-Passwörtern.
1
require_once('phpass-0.3/PasswordHash.php');
2
3
class Password {
4
5
  var $hasher;
6
7
  function __construct()
8
  {
9
    // 8 is the hash strength.  A larger value can be used for extra security.

10
    // TRUE makes the passwords portable.  FALSE is much more secure.

11
    $this->hasher = new PasswordHash(8, TRUE);
12
  }
13
  
14
 function hash($pass)
15
 {
16
    return $this->hasher->HashPassword($pass);
17
 }
18
 
19
 function check_password($pass, $hash){
20
    return $this->hasher->CheckPassword($pass, $hash);
21
 }
22
}

Die require_once()-Anweisung stellt sicher, dass wir die PasswordHash-Klasse von phpass verwenden können.

PasswordHash verwendet zwei Argumente in seinem Konstruktor:

  • eine Zahl, die die Hash-Stärke angibt
  • ein Boolescher Wert, ob die Passwörter portabel sein sollen oder nicht.

In diesem Fall werden wir unsere Passwörter portabel machen.

Dies bedeutet im Wesentlichen, dass der Hash nicht so stark ist. Wenn wir jedoch jemals den Server wechseln oder die Datenbank verschieben müssen, können wir eine Kopie erstellen. Wenn wir kein portables Hashing-Schema verwenden, besteht das Risiko, dass alle Benutzer neue Kennwörter erstellen, wenn die Datenbank verschoben wird.

Hinweis: Auch wenn wir eine stärkere Hashing-Funktion implementieren, sollten Benutzer dennoch ein sicheres Kennwort benötigen.

Ändern des Admin-Modells

1
   public function verify_user($email, $password)
2
   {
3
      $q = $this
4
            ->db
5
            ->where('email_address', $email)
6
            ->limit(1)
7
            ->get('users');
8
     
9
      if ( $q->num_rows > 0 ) {
10
         $result = $q->row();
11
         $this->load->library('password');
12
         
13
         //Make sure the hashes match.

14
         if($this->password->check_password($password, $result->password)){
15
          return $result;
16
         }  
17
      }
18
      return false;
19
   }

Zuvor haben wir den Benutzer anhand der E-Mail-Adresse und des Hash-Passworts ausgewählt. Jetzt ziehen wir den Benutzer basierend auf der E-Mail-Adresse aus der Datenbank. Dies bedeutet, dass wir das Passwort validieren müssen, bevor wir den Benutzer zurückgeben können.

Nachdem wir den Benutzer aus der Datenbank gezogen haben, laden wir die gerade erstellte Kennwortbibliothek und überprüfen, ob das eingegebene Kennwort mit dem gehashten Kennwort übereinstimmt.

Wenn die beiden Passwörter übereinstimmen, geben wir den Benutzer zurück, andernfalls geben wir false zurück.

Stellen Sie sicher, dass Sie die Passwortbibliothek verwenden, um ein neues Passwort für sich selbst zu hashen. Die Passwörter in Ihrer Datenbank sind jetzt ungültig!

Ändern der Benutzertabelle

Wir werden der Datenbank ein grundlegendes Berechtigungsfeld hinzufügen. Diese Berechtigung bestimmt, ob sich der Benutzer mit einer Zwei-Faktor-Authentifizierung anmeldet oder nicht.

Für Zwei-Faktor-Berechtigungen müssen wir der Benutzertabelle eine Spalte hinzufügen. Sie können dies über phpMyAdmin oder durch Ausführen der folgenden SQL tun.

1
ALTER TABLE users ADD two_factor_permission BOOLEAN NOT NULL;

Bei einem Wert von 1 in der Berechtigungsspalte verwendet der Benutzer die Zwei-Faktor-Authentifizierung.

Das SQL fügt der Benutzertabelle eine boolesche Spalte hinzu. Wir werden dies verwenden, um Benutzer zu verpflichten, die Zwei-Faktor-Authentifizierung zu verwenden oder sie zu umgehen.

Wenn Sie dies richtig gemacht haben, sollte in Ihrer Benutzertabelle eine neue Spalte angezeigt werden. Sie müssen dann einen aktuellen Datensatz aktualisieren oder einen neuen Datensatz einfügen, der two_factor_permission auf true (1) setzt.

Wenn diese Spalte auf false (0) gesetzt ist, kann der Benutzer die Zwei-Faktor-Authentifizierung umgehen. Dies ist ideal für Benutzer, die nicht die gleiche Sicherheitsstufe wie ein Administrator benötigen.


Schritt 3: Verwenden der Berechtigungseinstellung

Wir benötigen eine Möglichkeit, die sekundäre Authentifizierung zu umgehen sowie einen sekundären Authentifizierungsschritt in den Anmeldevorgang einzufügen.

Umgehen der sekundären Authentifizierung

Zunächst benötigen wir eine Möglichkeit, die sekundäre Authentifizierung zu umgehen. Dies bedeutet, dass wir den Benutzer im Admin-Controller überprüfen müssen.

1
    if ( $res !== FALSE ) {
2
        $_SESSION['username'] = $res->email_address;
3
        if ( $res->two_factor_permission ) {
4
          $this->_second_auth($res->email_address);
5
          return;
6
        }
7
        else {
8
          $_SESSION['logged_in'] = TRUE;
9
          redirect('welcome');
10
        }
11
    }

Dies prüft, ob der Benutzer mit unserem Zwei-Faktor-System angemeldet sein soll.

Wenn der Benutzer die Zwei-Faktor-Authentifizierung verwenden soll, soll er zur sekundären Authentifizierungsseite wechseln, ohne sich anzumelden.

Anstatt den Benutzer umzuleiten, können wir die Funktion _second_auth() aufrufen und die Seite laden lassen. Die Anweisung "return" vermeidet das Laden des Anmeldeformulars.

Wir haben eine neue Sitzungsvariable logged_in erstellt, mit der wir überprüfen, ob der Benutzer angemeldet ist. Dies bedeutet, dass wir einige Änderungen an den Weiterleitungen vornehmen müssen.

Weiterleitungen korrigieren

Es gibt zwei Weiterleitungen, die geändert werden müssen: Die erste befindet sich in der Indexfunktion des Admin-Controllers.

1
if ( isset($_SESSION['logged_in']) && $_SESSION['logged_in'] === TRUE ) {
2
  redirect('welcome');
3
}

Der andere befindet sich im welcome Controller. Wir müssen sicherstellen, dass der Benutzer nicht angemeldet ist, bevor wir umleiten.

1
if ( !isset($_SESSION['logged_in']) || $_SESSION['logged_in'] !== TRUE ) {
2
  redirect('admin');
3
}

Einfügen einer sekundären Authentifizierung

Jetzt müssen wir uns um die sekundäre Authentifizierung kümmern.

In der admin/index-Funktion rufen wir _second_auth() auf, schreiben wir also eine Grundfunktion.

1
  public function _second_auth ($username)
2
  {
3
    echo "Welcome $username, you are looking at a secondary authentication page.";
4
  }

Schritt 4: Erstellen der Ansicht

Herkömmliche Authentifizierungssysteme behandeln Anmeldungen als einen einzigen Schritt.

User enters username and password then is logged inUser enters username and password then is logged inUser enters username and password then is logged in

Duo gibt uns ein bisschen JavaScript und HTML zum Einfügen zwischen den beiden Schritten. Dies bedeutet, dass wir eine Ansicht mit dem erforderlichen Code erstellen müssen.

User enters username and password then is prompted for phone verification then is logged inUser enters username and password then is prompted for phone verification then is logged inUser enters username and password then is prompted for phone verification then is logged in

Erstellen wir eine neue Ansicht mit dem Namen second_auth.php im Ordner views. Wir müssen den von Duo bereitgestellten Iframe und das JavaScript einfügen, damit es funktioniert.

Sie sollten eine Seite mit der grundlegenden HTML-Struktur erstellen. Folgendes kann in den Körper eingebracht werden:

1
        <iframe id="duo_iframe" width="100%" height="500" frameborder="0"></iframe>
2
        <script type="text/javascript" src="/path/to/Duo-Web-v1.js" ></script>

In einem typischen Setup würden Sie Ihr gesamtes JavaScript in einem Ressourcenordner aufbewahren. Hier haben wir einen resources-Ordner im Stammverzeichnis unserer Site mit einem Unterordner 'js' abgelegt, der die Web SDK-JavaScript-Datei enthält.

Unser src wird aussehen wie:

1
src="<? echo base_url(); ?>resources/js/Duo-Web-v1.js"

Wir müssen auch dieses zweite Bit JavaScript hinzufügen.

1
<script type="text/javascript" >
2
    Duo.init({
3
        'host':'<?php echo $host; ?>',
4
        'post_action':'<?php echo $post_action; ?>',
5
        'sig_request':'<?php echo $sig_request; ?>'
6
    });
7
</script>

Wir werden diese Daten in Kürze vom Controller generieren.

Einfügen eines Formulars

Wenn Sie dem vorherigen Tutorial gefolgt sind, sollten Sie CodeIgniter zum Schutz vor CSRF konfiguriert haben.

Da das JavaScript Daten an unseren Controller sendet, sucht CodeIgniter nach dem CSRF-Token. Wenn wir dieses Token nicht haben, erhalten wir eine Fehlermeldung.

Das von uns verwendete JavaScript sendet ein Formular mit der ID "duo_form". Alles was wir tun müssen, ist es zu schaffen.

1
echo form_open('admin', array('id'=> "duo_form"));
2
echo form_close();

Bei Verwendung der Formularklasse fügt CodeIgniter das Token automatisch ein. Wenn das Formular veröffentlicht wird, findet CodeIgniter das Token und lässt uns fortfahren.


Schritt 5: Vorbereiten der Daten

Zurück im admin-Controller müssen wir einige Daten in unserer Funktion _second_auth() generieren.

Der Host ist die API-URL, die Sie bei der Anmeldung bei Duo erhalten haben. Diese URL sollte ungefähr so aussehen wie api-xxxxxxxx.duosecurity.com (wobei 'xxxxxxxx' eine eindeutige Zeichenfolge ist, die an Ihr Duo-Konto gebunden ist).

1
$data['host'] = "api-xxxxxxxx.duosecurity.com";

Denken Sie daran, den Host durch Ihre spezifische URL zu ersetzen. Die obige URL funktioniert nicht.

Die Post-Aktion ist die URL, die die Antwort verarbeitet, sobald der Benutzer versucht hat, sich bei Duo zu authentifizieren.

Wir werden eine weitere Funktion im Admin-Controller erstellen, um das Post-Back zu erledigen. Im Moment werden wir die Funktion process_second_auth() benennen.

1
  $data['post_action'] = base_URL() . "admin/process_second_auth";

Laden des PHP Web SDK

Stellen Sie sicher, dass Sie 'duo_web.php' in 'duo.php' umbenennen, um CodeIgniter-Fehler zu vermeiden.

Wenn Sie die neueste Version von duo_web.php nicht heruntergeladen haben, können Sie sie von Duos Web SDK GitHub-Seite herunterladen.

Da das Web SDK als PHP-Klasse geliefert wird, können wir es in "duo.php" umbenennen und in unserem Ordner "application/library" ablegen.

Nachdem Sie die Datei in den libraries-Ordner gelegt haben, können wir sie in unseren Controller laden.

1
  public function _second_auth($username)
2
  {
3
    $this->load->library('duo');
4
    
5
    $data['host'] = "api-xxxxxxxx.duosecurity.com";
6
    $data['post_action'] = base_URL() . "admin/process_second_auth";
7
    
8
    echo "Welcome $username, you are looking at a secondary authentication page.";
9
  }

Generieren der signierten Anfrage

Um zu verstehen, wie sig_request generiert wird, müssen Sie verstehen, was wir generieren.

Die Variable $akey muss mindestens 40 Zeichen lang sein, sonst gibt die Duo-Bibliothek einen Fehler zurück!

Das Duo Web SDK erstellt zwei signierte Token, eines mit dem geheimen Schlüssel, den sie Ihnen geben, und eines mit einem Anwendungsschlüssel, den Sie erstellen.

sig_request ist eine Kombination der beiden Token.

Durch das Erstellen Ihres eigenen Anwendungsschlüssels erhalten Sie eine zweite Sicherheitsebene. Ein Angreifer benötigt sowohl den geheimen Schlüssel von Duo als auch Ihren persönlichen Anwendungsschlüssel, um einen Token zu fälschen.

Jetzt generieren wir die 'sig_request'. Duo stellt Ihnen beim Erstellen einer Integration einen Integrationsschlüssel und einen geheimen Schlüssel zur Verfügung.

Stellen Sie sicher, dass Sie den folgenden Text durch den Integrationsschlüssel und den geheimen Schlüssel ersetzen, die Sie erhalten haben. Sie müssen Ihren eigenen geheimen Schlüssel erstellen. Es muss mindestens 40 Zeichen lang sein und sollte so zufällig wie möglich sein.

1
public function _second_auth($username)
2
{
3
  $this->load->library('duo');
4
  
5
  // Duo Integration Key

6
  $ikey = "REPLACE WITH YOUR DUO INTEGRATION KEY";
7
  
8
  // Duo Secret Key

9
  $skey = "REPLACE WITH YOU DUO SECRET KEY";
10
  
11
  // Personal Application Key

12
  $akey = "CREATE AN APPLICATION KEY";
13
  
14
  $data['host'] = "api-xxxxxxxx.duosecurity.com";
15
  $data['post_action'] = base_URL() . "admin/process_second_auth";
16
  $data['sig_request'] = $this->duo->signRequest($ikey, $skey, $akey, $username);
17
  
18
  echo "Welcome $username, you are looking at a secondary authentication page.";
19
}

Duos signRequest() generiert die Token und gibt sie als Zeichenfolge zurück, die an sig_request übergeben werden soll.

Jetzt müssen wir die Daten in die zuvor erstellte Ansicht laden.

1
public function _second_auth($username)
2
{
3
  $this->load->library('duo');
4
  
5
  // Duo Integration Key

6
  $ikey = "REPLACE WITH YOUR DUO INTEGRATION KEY";
7
  
8
  // Duo Secret Key

9
  $skey = "REPLACE WITH YOUR DUO SECRET KEY";
10
  
11
  // Personal Application Key

12
  $akey = "CREATE AN APPLICATION KEY";
13
  
14
  $data['host'] = "api-xxxxxxxx.duosecurity.com";
15
  $data['post_action'] = base_URL() . "admin/process_second_auth";
16
  $data['sig_request'] = $this->duo->signRequest($ikey, $skey, $akey, $username);
17
  
18
  $this->load->view('second_auth', $data);
19
}

Wenn Sie jetzt versuchen, sich anzumelden, sollte diese Seite angezeigt werden:

Duo Enrollment Page

Dies ist das Anmeldeformular. Sie können Ihr Handy hier registrieren, aber wir haben nichts, um die sekundäre Authentifizierung zu verarbeiten, sodass Sie nicht angemeldet werden.

Wenn Sie überhaupt nichts sehen, sehen Sie sich die Seitenquelle für Fehlermeldungen an. Alle Fehler mit den Daten werden im <script>-Tag angezeigt.

Wenn "Zugriff verweigert" angezeigt wird, stellen Sie sicher, dass Sie den Integrations- und Geheimschlüssel von der Duo Security-Website eingegeben haben.


Schritt 6: Verarbeiten der sekundären Authentifizierung

Wir haben unsere Post-Aktion als admin/process_second_auth eingerichtet, daher müssen wir eine process_second_auth()-Funktion erstellen.

1
public function process_second_auth()
2
{
3
  if ( isset($_SESSION['logged_in']) && $_SESSION['logged_in'] === TRUE ) {
4
    redirect('welcome');
5
  }
6
}

Da diese Funktion eine eigene URL hat, müssen wir angemeldete Benutzer umleiten.

Wir müssen die Duo-Bibliothek erneut laden, um die Daten zu validieren.

1
$this->load->library('duo');
2
3
// Same keys used in _second_auth()

4
$ikey = "REPLACE WITH YOUR DUO INTEGRATION KEY";
5
$skey = "REPLACE WITH YOUR DUO SECRET KEY";
6
$akey = "REPLACE WITH YOUR APPLICATION KEY";

Wir benötigen die gleichen $ikey, $skey und $akey aus der Funktion _second_auth(), um die veröffentlichten Daten zu validieren.

Das JavaScript sendet eine sig_response von den Duo-Servern zurück.

1
$sig_response = $this->input->post('sig_response');
2
$username = $this->duo->verifyResponse($ikey, $skey, $akey, $sig_response);

Sobald wir sig_response aus den veröffentlichten Daten abgerufen haben, führen wir sie über die Funktion verifyResponse() aus. Dies gibt NULL zurück, wenn die Token nicht übereinstimmen, oder einen Benutzernamen, wenn sie gültig sind.

1
if ( $username ) {
2
  $_SESSION['logged_in'] = TRUE;
3
  redirect('welcome');
4
}
5
else{
6
  redirect('admin');
7
}

Zuletzt überprüfen wir, ob ein Benutzername zurückgegeben wurde, und beenden die Anmeldung, indem wir den Wert von $_SESSION['logged_in'] auf true setzen.

Alles in allem sollte die Funktion so aussehen:

1
public function process_second_auth()
2
{
3
  if ( isset($_SESSION['logged_in']) && $_SESSION['logged_in'] === TRUE ) {
4
    redirect('welcome');
5
  }
6
  
7
  $this->load->library('duo');
8
  
9
  // Same keys used in _second_auth()

10
  $ikey = "REPLACE WITH DUO'S INTEGRATION KEY";
11
  $skey = "REPLACE WITH DUO'S SECRET KEY";
12
  $akey = "REPLACE WITH YOUR APPLICATION KEY";
13
  
14
  $sig_response = $this->input->post('sig_response');
15
  $username = $this->duo->verifyResponse($ikey, $skey, $akey, $sig_response);
16
  
17
  if ( $username ) {
18
    $_SESSION['logged_in'] = TRUE;
19
    redirect('welcome');
20
  }
21
  else{
22
    redirect('admin');
23
  }
24
}

Jetzt sollten Sie in der Lage sein, sich mit Zwei-Faktor-Authentifizierung anzumelden. Probieren Sie es aus!


Schlussfolgerung

Hoffentlich haben Sie Ihr eigenes Zwei-Faktor-Authentifizierungssystem für CodeIgniter eingerichtet!

Was könnten Sie noch tun? In Bezug auf die Sicherheit gibt es viel zu tun, aber die größte Verbesserung wäre die Verfolgung von Benutzeraktionen.

Ein gutes Sicherheitssystem ist nicht nur sicher: Es hilft Ihnen zu erkennen, woher eine Sicherheitsanfälligkeit stammt. Sie sollten Anmeldeversuche und andere Aktionen verfolgen, um die Identifizierung von Angreifern zu erleichtern.

Danke fürs Lesen! Wenn Sie Probleme haben, hinterlassen Sie einen Beitrag in den Kommentaren.

Advertisement
Did you find this post useful?
Want a weekly email summary?
Subscribe below and we’ll send you a weekly email summary of all new Code tutorials. Never miss out on learning about the next big thing.
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.