Tweefactorauthenticatie kan voor de gebruiker een zeer banaal proces lijken. Velen zijn er al lang aan gewend dat het bij het gebruik van veel toepassingen niet voldoende is om een vertrouwde combinatie van login en wachtwoord in te voeren. Er wordt een extra verificatiefactor ingevoerd voor extra veiligheid en om ongeoorloofde toegang te voorkomen. In de meeste gevallen is dat een unieke code die per e-mail of SMS kan worden ontvangen.
In deze tutorial leren we hoe u tweefactorauthenticatie kunt implementeren in AppMaster. Als voorbeeld zal het versturen van de code naar de mail worden gebruikt. We zullen analyseren welke modules moeten worden aangesloten, welke instellingen moeten worden gemaakt, welk bedrijfsproces moet worden gecreëerd, en hoe het eindresultaat in de praktijk kan worden gecontroleerd.
Laten we eerst eens kijken naar het algemene plan. Welke stappen moeten worden uitgevoerd in ons bedrijfsproces?
- Verificatie van de aanmelding (controleren of de gebruiker daadwerkelijk geregistreerd is).
- Controle of het wachtwoord correct is.
- Verzending van een bevestigingscode per post of SMS.
- Controle van de relevantie van de code.
- Controle van de juistheid van de code.
- Voltooiing van de authenticatie.
Voorbereidende fase
Nog voordat u begint met het ontwerpen van tweefactorauthenticatie, moet u er in de fase van de gebruikersregistratie zeker van zijn dat:
- De gebruikersgegevens moeten een e-mail bevatten. Deze zal worden gebruikt om de verificatiecode te versturen. E-mail wordt vaak gebruikt als login, en we zullen zo'n voorbeeld bekijken.
- De login is uniek. Twee verschillende gebruikers met dezelfde login kunnen niet bestaan in het systeem.
Voor het gemak van het oplossen van deze (en vele andere) taken is de Auth module standaard geïnstalleerd in elk AppMaster project. Hij bevat de nodige databasemodellen, bedrijfsprocesblokken en eindpunten voor het gebruik ervan.
Verificatie van de aanmelding
Login, wachtwoord en verificatiecode worden gebruikt als invoerparameters van het bedrijfsproces. Maar in het eerste stadium hebben we alleen een login nodig. Het zou helpen om er zeker van te zijn dat deze gebruiker bestaat. Hij is geregistreerd, en informatie daarover is opgeslagen in de database.
Hiervoor zoekt het DB: Search User blok in de database naar een gebruiker met de opgegeven login. Zorg ervoor dat de SearchExact = True parameter in te stellen om een exacte match te zoeken.
De ontvangen gegevens worden doorgegeven aan het Array Element blok met index 0 (het tellen begint vanaf nul, en de enige gevonden waarde zal altijd overeenkomen met index 0 in de array).
Het blok Is Null blok controleert of de gebruiker daadwerkelijk is gevonden. En afhankelijk van het resultaat (True/False), zal het If-Else blok zal ofwel het bedrijfsproces onderbreken met een foutmelding (Raise Error blok) of stuurt het verder.
Controle van het wachtwoord
In dit stadium moet worden gecontroleerd of het wachtwoord van de gebruiker correct is ingevoerd.
En hier is het essentieel te begrijpen dat wachtwoorden niet expliciet in de database worden opgeslagen. De Bcrypt functie hashed ze, en alleen de resulterende hash wordt opgeslagen in de database. Daarom, zelfs als we aannemen dat er een gegevenslek optreedt, zullen aanvallers nog steeds niet in staat zijn om gebruikerswachtwoorden te vinden; ze zijn veilig versleuteld.
Daarom kun je niet zomaar het wachtwoord uit de database halen en het vergelijken met het ingevoerde wachtwoord. Je moet de hash van het wachtwoord krijgen en die gebruiken om te vergelijken. Om dit probleem op te lossen wordt het Auth: Probe Password blok gebruikt. Als invoerparameters neemt het het door de gebruiker ingevoerde wachtwoord (password) en de hash van het in de database opgeslagen wachtwoord (hashed_password) en converteert het naar het gegevenstype String (het To String blok).
Afhankelijk van het resultaat, zoals in de vorige stap, met behulp van het If-Else blok, geven we ofwel een foutmelding (Raise Error, Message = Password is wrong) of leiden we het proces naar de volgende fase.
Uitbreiding gebruikersmodel
Voor de volgende stap moet u een kleine wijziging aanbrengen in het gebruikersmodel en informatie toevoegen over de code die moet worden bevestigd.
Over het algemeen bevat het model User in eerste instantie velden die voor deze taak kunnen worden gebruikt - Confirmed, Confirmation code, Confirmation code expires at. Maar in dit voorbeeld gaan we ervan uit dat deze velden alleen worden gebruikt voor registratie en initiële accountverificatie.
Laten we voor meer duidelijkheid van het proces een afzonderlijk twofa (two-factor authentication) model aanmaken, het User model ermee associëren (1-op-1 relatie, has one), en één veld toevoegen - code (String type).
Het verzenden van e-mails voorbereiden
Om e-mails met bevestigingscodes te versturen, moet men een voorbereiding treffen. Een van de meest toegankelijke opties is het gebruik van de Custom SMTP module, die u moet installeren en configureren.
Bij gebruik van Gmail zijn de meeste instellingen al standaard ingesteld, en moet u uw gebruikersnaam en wachtwoord toevoegen. Bij gebruik van andere mailservers zou het helpen als u hun documentatie raadpleegt om de nodige gegevens te verkrijgen.
In dat geval moet u misschien de beveiligingsinstellingen van de mailserver enigszins wijzigen. Gmail kan bijvoorbeeld standaard verbindingen met toepassingen van derden blokkeren, en u moet deze beperking in de instellingen opheffen.
Een verificatiecode versturen
We hebben de login en het wachtwoord gecontroleerd en alle noodzakelijke voorbereidingen getroffen, dus nu kunt u overgaan tot het versturen van een brief met een bevestigingscode.
Het blok Custom SMTP: Send Email blok gebruikt een array van adressen als bestemming. Dus ook al moet u een brief naar slechts één adres sturen, het moet aan de array worden toegevoegd. Hiervoor wordt het Append Array blok gebruikt.
De volgende stap is het genereren van een verificatiecode. Het blok Random string blok is hiervoor geschikt. We sturen een code bestaande uit 6 willekeurige getallen en maken de juiste instellingen. Length = 6, With 0-9 = True, alle andere parameters = False.
Vervolgens moet u de tekst van de brief maken. Hiervoor gebruikt u het Concat Strings blok om verklarende tekst toe te voegen aan de gegenereerde code (First = Verification code: ), het resultaat te converteren naar het datatype Text (To Text blok), en verbindt u het resultaat met de body parameter van het blok voor het verzenden van e-mails.
Voor de uiteindelijke verzending hoeft u alleen nog maar het onderwerp van de brief (subject) en de afzender (from_name) op te geven.
Maar het is niet voldoende om alleen de code te versturen; deze moet ook worden opgeslagen in de gegevens van de gebruiker. Je moet immers de juistheid ervan controleren wanneer de gebruiker de code ontvangt en ter bevestiging terugstuurt.
Hiervoor gebruiken we het model twofa, dat we eerder voorzichtig hebben aangemaakt. Als dit de eerste keer is dat een code wordt ingediend, moet u deze aanmaken met informatie over de gebruiker van wie hij is. In geval van hergebruik is het noodzakelijk de bestaande inzending te patchen, met vermelding van zijn ID en nieuwe code.
De laatste stap van de fase is het gebruik van het Raise Error blok een bericht terug te sturen over het verzenden van de code naar de e-mail.
Controle van de relevantie van de code
Het is de moeite waard om voor extra beveiliging te zorgen en de code te beschermen tegen een banale opsomming. Het zou verstandig zijn het aantal invoerpogingen, hun frequentie en de levensduur van de ingediende code te beperken. Wij zullen niet al deze voorbeelden analyseren; beveiligingseisen zijn voor elk project anders en kunnen veel verschillende voorwaarden omvatten. Wij beperken ons tot het controleren van de relevantie van de code aan de hand van de geldigheidsduur.
Laten we het Current date & time blok gebruiken om de huidige tijd op te vragen. Verbind het met de parameter B van het Date & time difference blok. We zullen het UpdatedAt veld van het twofa model als de parameter A.
Als resultaat krijgen we Time span - het verschil tussen twee tijdstippen. Er moet alleen nog worden nagegaan of dit verschil een bepaalde geselecteerde waarde overschrijdt. In ons voorbeeld is dat 5 minuten, die we instellen als de statische waarde B van het Greater blok.
Het blok If-Else blok zal het vergelijkingsresultaat gebruiken om het proces verder te sturen. Als True (het verschil groter is dan 5 minuten), keert het proces terug naar de stap van het verzenden van de brief; de gebruiker ontvangt een bijgewerkte code. In het geval van False (de code is vers en up-to-date), zal het mogelijk zijn om door te gaan met het controleren van deze code.
Controle van de code
De laatste fase van de authenticatie is het controleren van de ontvangen code.
Het blok Equal blok moet valideren of de door de gebruiker ingevoerde code overeenstemt met de code die is opgeslagen in het model twofa dat aan de gebruiker is gekoppeld. Als dit niet het geval is en de code onjuist is opgegeven (If-Else -> False), dan moet er een foutmelding komen (Raise Error, Message = Code is wrong). Als de vergelijking de overeenkomst bevestigt, kunt u doorgaan naar de laatste authenticatiefase.
Hiervoor gebruiken we het Auth: Authentication blok en krijgen we informatie over de gebruiker met zijn autorisatietoken. Die geven we door aan het End blok als resultaat van een succesvolle authenticatie.
Aanmaken van een eindpunt
Het bedrijfsproces is aangemaakt, maar is nog niet beschikbaar voor gebruik. U moet een eindpunt maken dat dit bedrijfsproces uitvoert.
Een redelijke oplossing zou zijn om het standaard authenticatie-eindpunt (POST /Auth) te gebruiken. Het zal voldoende zijn om het bedrijfsproces ervan te vervangen en het zojuist aangemaakte proces te installeren. Aldus wordt eenvoudige authenticatie uitgeschakeld, en wordt in plaats daarvan tweefactorauthenticatie gebruikt.
Publicatie en testen
Dit voltooit de creatie van twee-factor authenticatie. U kunt het resultaat publiceren en in actie controleren. Hiervoor is het handig om Swagger te gebruiken, dat kan worden geopend door te klikken op de naam van het Deploy plan in het gedeelte Project API van de knop Preview.
Het enige wat rest is het gewenste eindpunt te vinden in de lijst, de gebruikersgegevens in te voeren en de uitvoering te starten met de knop Execute. Als er tijdens het testen fouten worden gevonden, ga dan terug naar het bedrijfsproces en breng de nodige wijzigingen aan.