Matroids Matheplanet Forum Index
Moderiert von matph
Informatik » Programmieren » Beispielprojekt: Erstellen eines Login-Forms mit Spring-Boot und Javascript
Autor
Universität/Hochschule J Beispielprojekt: Erstellen eines Login-Forms mit Spring-Boot und Javascript
Lucky_7
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 21.01.2018
Mitteilungen: 204
  Themenstart: 2021-11-09

Ich möchte gerne ein Login-System erstellen. Hierzu habe ich zwei Spring-Boot Projekte aufgesetzt, einen Server und einen Client. Der Server besteht in erster Linie aus dem RestController: \sourceon Java @RestController @CrossOrigin("http://localhost:9090") public class LoginController { @Autowired UserRepository userRepository; @GetMapping("/login") public User home(@RequestParam("username") String username, @RequestParam("password") String password) { User queriedUser = userRepository.findByUsername(username); if (queriedUser.getPassword().equals(password)) { return queriedUser; } return null; } \sourceoff Außerdem gibt es noch die User-Klasse und das User-Repository, also das Java-Objekt, welches die Datenbank repräsentiert. Wenn ein GET-Request der Form https://localhost:9090/login/username?someName&password?somePassword an diesen Server geschickt wird, schaut dieser nach ob es den Username in der Datenbank gibt und ob das Password mit dem hinterlegten Passwort übereinstimmt. Trifft all das zu, wird eine Klasse vom Typ User in JSON zurück an den Client geschickt. Ansonsten wird null zurückgeliefert. Auf der Client-Seite gibt es einen Controller, der beim Eingeben der URL http://localhost:9090 dafür sorgt, dass eine login.html Datei angezeigt wird. Diese Datei enthält ein
Element. An dieses Element habe ich einen submit-Listener gesetzt, der wiederum gesetzt wird, wenn das document.ready() ist. Wenn ich nun auf den Submit-Button klicke, wird ein GET-Request an meinen Server geschickt: \sourceon Javascript function login() { $.ajax({ method: 'GET', dataType: 'json', url: "http://localhost:8080/login", data: { username: $("#username").val(), password: $("#password").val() }, success: [ function(response) { if (response === null) { setErrorMessage(); } else { clearErrorMessage(); let newDoc = document.open("login", "replace"); newDoc.write("home"); newDoc.close(); } }] }) } function setErrorMessage() { console.log("inside setErrorMessage()"); $("#login .form__message").html("Wrong username or password"); $("#login .form__message").addClass("form__message--error"); } function clearErrorMessage() { $("#login .form__message").html(""); $("#login .form__message").removeClass("form__message--error"); } \sourceoff Der GET-Request wird erfolgreich ausgeführt. Wenn ich eine valide Username-Password-Kombi eingebe, dann wird mir eine neue Seite angezeigt. Leider ist das nicht die home.html, die ich gerne sehen würde, sondern einfach nur der String "home" auf http://localhost:9090/?. Und das ist meine erste Frage: Wie kann ich mir die home.html Seite anzeigen lassen? Sowohl login.html als auch home.html liegen in resources/templates. Ich weiß, dass es eine load()-Methode von jQuery gibt. Die ist aber meines Wissens dafür gedacht etwas von einem Server anzufragen. Meine html-Seite liegt ja beim Client. Die andere Frage, die ich habe, ist folgende: Wenn ich eine falsche Username-Password-Kombi eingebe, dann passiert einfach nichts. Offenbar funktioniert also die Überprüfung response === null in meinem Javascript-Code nicht. Ich weiß aber nicht wieso. Da ich das zum ersten Mal mache, sind in diesem Beispiel vermutlich noch einige Fehler enthalten. Es wäre klasse, wenn mir jemand helfen könnte zu verstehen, was hier falsch läuft.


   Profil
Scynja
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 23.02.2011
Mitteilungen: 522
Wohnort: Deutschland
  Beitrag No.1, eingetragen 2021-11-09

Hallo Lucky_7 mit \sourceon JavaScript location.href = "https://www.meineseite.net/home"; \sourceoff Kannst du danach die Seite wechseln. Wie überprüfst du denn, ob du angemeldet bist? Setzt du einen Cookie? Bezüglich deines Beispiels noch ein paar Anmerkungen: - Man speichert auf Servern keine Passwörter im Klartext - Normalerweise nutzt man SpringSecurity für die Authentifizierung. - Dein workflow ist etwas komisch. Das ist aber vielleicht dem Minimalbeispiel geschuldet. - Ich würde dir empfehlen z. B. OAuth2 zu implementieren. Das ist ein weit verbreitetes Standardverfahren zur Authentifizierung. Es gibt auch bereits fertige OAuth2-Server, die man als Docker-Container starten kann. Implementiere den Server nur selbst, wenn du dich für die Servertechnik interessierst. Du wirst ihn nämlich höchstwahrscheinlich danach wegwerfen können.


   Profil
Lucky_7
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 21.01.2018
Mitteilungen: 204
  Beitrag No.2, vom Themenstarter, eingetragen 2021-11-11

Hallo Scynja, super, vielen Dank für deine Antwort! Ich setze jetzt in meinem JavaScript Code das location.href, sodass ich bei erfolgreichem GET-Request die Seite wechsle. Das funktioniert einwandfrei :-) Ich habe mir auch einmal angeschaut wie Spring Security funktioniert. Ich bin mir nur nicht sicher ob ich Spring Security auf dem Server oder im Client implementieren muss. Ich habe das Gefühl, dass ich Spring Security auf dem Server implementieren muss, aber ich kann mir gerade nicht vorstellen wie ich dann eine eigene Login-Page anzeigen kann: In der SecurityConfiguration Klasse muss ich in der configure(HttpSecurity http) Methode die URLs definieren, auf die der Client zugreifen darf. Beispielsweise so: \sourceon Java @Override protected void configure(HttpSecurity http) throws Exception { http.authorizeRequests() .antMatchers("/admin").hasRole("ADMIN)") .antMatchers("/user").hasAnyRole("ADMIN", "USER") .antMatchers("/").permitAll() .and().formLogin(); } \sourceoff Wenn mein Server, auf dem ich Spring Security implementiert habe, nun also auf localhost:8080 läuft, dann würde ich nach der Eingabe der URL http://localhost:8080/user in meinem Browser zu einer Login-Page weiter geleitet werden, die auf http://localhost:8080/login liegt. Diese Seite wird standardmäßig von Spring Security angelegt. Nun kann ich einfach meine Login-Daten eingeben und Spring Security schaut nach ob diese Daten valide sind. Ich habe schon gelesen, dass ich diese Login-Page auch anpassen kann, bzw. über der Builder-Methode .loginPage("/login") auf meine eigene Login-Page verweisen kann. Aber das will ich ja eigentlich gar nicht. Ich möchte doch, dass die Login-Page bei meinem Client liegt. Wie kann ich das erreichen?


   Profil
Scynja
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 23.02.2011
Mitteilungen: 522
Wohnort: Deutschland
  Beitrag No.3, eingetragen 2021-11-11

Hallo Lucky_7, es ist nicht unüblich, dass die Loginseite woanders liegt. Vielleicht hast du schon einmal bei irgend einer Webseite "Login with facebook" oder "Login with google" gesehen. Spring Security wird im Server implementiert. Im Client implementiert man das Gegenstück. Kannst du bitte einmal deine angestrebte Architektur skizzieren? Was sind die Haupttechnologien für BE, für FE, für DB, für LoginServer. Welches Loginverfahren möchtest du überhaupt implementieren? Basicauth, Oauth, ...


   Profil
Lucky_7
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 21.01.2018
Mitteilungen: 204
  Beitrag No.4, vom Themenstarter, eingetragen 2021-11-11

Hallo Scynja, erst einmal vielen Dank, dass du mir hier weiterhilfst! Ich versuche eigentlich nur eine ganz einfache Webapp zu schreiben, die genau zwei Seiten hat: 1. Eine Login-Seite 2. Eine Haupt-Seite, auf der eine Tabelle angezeigt wird, die den Stand einer Datenbank wiedergibt. Das ist ein Projekt, an dem ich lernen möchte. Ich habe noch niemals eine Webapp geschrieben und ich habe auch nicht viel Erfahrung in der Softwareentwicklung. Ich möchte durch das Projekt etwas Erfahrung sammeln und dazu lernen. Was ist nun also meine angestrebte Architektur? Um ehrlich zu sein, habe ich mir darüber keine Gedanken gemacht. Ich kann dir aber sagen, welche Technologien ich verwenden möchte: Da ich Java-Kenntnisse habe, würde ich für das Backend gerne Java verwenden. Für den Datenbank-Zugriff verwende ich Spring.JPA, also Hibernate. Spring-Boot verwende ich für die Definition der REST-Schnittstelle. Und für das Frontend verwende ich einfaches Javascript und jQuery. Hiermit kenne ich mich allerdings nicht so gut aus. Meine Datenbank ist eine MySQL Datenbank, die auf dem localhost läuft. Die Datenbank enthält bisher eine einzige Tabelle "login". Und diese Tabelle hat die Spalten id, username, password, active (boolean), roles (String, entweder ROLE_USER oder ROLE_ADMIN). Und jetzt versuche ich einmal zu beschreiben, was ich bisher umgesetzt habe: Client: Die Ordner-Struktur des Clients ist folgende: https://matheplanet.com/matheplanet/nuke/html/uploads/b/49478_clientApp.PNG Der LoginController zeigt einfach nur die Login.html Seite an: \sourceon Java @Controller public class LoginController { @GetMapping("/") public String login() { return "login"; } } \sourceoff Die Login.html-Seite hat keinen Body. Sie enthält einfach nur ein

Login

\sourceoff Der Login funktioniert aber nicht. Mir wird einfach das Login.html ohne CSS angezeigt, auch wenn ich die korrekte Username-Password-Kombi eingebe.



   Profil
Scynja
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 23.02.2011
Mitteilungen: 522
Wohnort: Deutschland
  Beitrag No.5, eingetragen 2021-11-11

Hallo Lucky, \sourceon Java @GetMapping("/login") public String login() { return "login"; } \sourceoff Das hier sagt folgendes: Wenn du einen get-Request auf /login machst (jeder Seitenaufruf ist auch ein /get-Request), dann liefere das Wort login als Antwort zurück. Das ist das, was du siehst. Du hast bis jetzt schon ein sehr komplexes Setup, was das nachstellen nicht gerade einfach macht. Mehr dazu später. Ich muss mir erst einmal ein Minimalbeispiel ohne Datenbank und dem ganzen Rattenschwanz aufbauen. Ich kann dann später noch mehr dazu schreiben. Deine Frontendarchitektur reicht vermutlich für den ersten Wurf. Allerdings sollte dir bewusst sein, dass das meiste nur noch SinglePage-Applikationen sind. Es gibt dann zwar noch JavaServerFaces, die werden allerdings genauso wie JQuery immer seltener verwendet. nur in alten Bestandsprojekten findet man sie häufig.


   Profil
Lucky_7
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 21.01.2018
Mitteilungen: 204
  Beitrag No.6, vom Themenstarter, eingetragen 2021-11-14

Hallo Scynja, damit ich diese Syntax für meinen Get-Request verwenden kann, habe ich die Thymeleaf-dependency meiner pom.xml hinzugefügt: \sourceon Maven org.springframework.boot spring-boot-starter-thymeleaf \sourceoff Das scheint auch zu funktionieren, mir wird, wenn ich im Browser die Domain des Clients eingebe (http://localhost:9090) folgende Seite angezeigt: https://matheplanet.com/matheplanet/nuke/html/uploads/b/49478_login_snap.PNG Und in der Browser-Konsole sehe ich auch keinen Fehler. Allerdings wurde das CSS-Stylesheet ganz eindeutig nicht angewandt. Wenn ich dann aber meine Login-Daten eingebe, dann wird mir dieser Post-error angezeigt: https://matheplanet.com/matheplanet/nuke/html/uploads/b/49478_post_error.PNG Tja. Ehrlich gesagt bin ich ratlos, ich dachte das würde funktionieren. (Übrigens: Falls du es nicht gesehen hast (ich finde das hier nicht immer offensichtlich) - zum Nachstellen des Projektes habe ich dir eine PM geschickt.)


   Profil
zippy
Senior Letzter Besuch: in der letzten Woche
Dabei seit: 24.10.2018
Mitteilungen: 3943
  Beitrag No.7, eingetragen 2021-11-14

\quoteon(2021-11-14 12:20 - Lucky_7 in Beitrag No. 6) https://matheplanet.com/matheplanet/nuke/html/uploads/b/49478_post_error.PNG Tja. Ehrlich gesagt bin ich ratlos, ich dachte das würde funktionieren. \quoteoff Ich habe mir den Rest des Threads nicht angeschaut, aber oben ist doch ein POST-Request zu sehen, während du hier ein GET-Mapping definierst: \quoteon(2021-11-11 21:25 - Lucky_7 in Beitrag No. 4) \sourceon Java @Controller @CrossOrigin("http://localhost:9090") public class LoginController { @GetMapping("/home") public String home() { return "home"; } @GetMapping("/login") public String login() { return "login"; } } \sourceoff \quoteoff


   Profil
Lucky_7
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 21.01.2018
Mitteilungen: 204
  Beitrag No.8, vom Themenstarter, eingetragen 2021-11-14

Hallo zippy, ja, das ist richtig. Ich habe ehrlich gesagt angenommen, dass Spring Security den Post-Request auf "/login" abfängt und dann authentifiziert.


   Profil
Scynja
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 23.02.2011
Mitteilungen: 522
Wohnort: Deutschland
  Beitrag No.9, eingetragen 2021-11-14

Hallo Lucky, Du must die css-Dateien auch erlauben. In etwa so: \sourceon Java .antMatchers("/", "/css/**", "/js/**", "/images/**").permitAll() \sourceoff Die Authentifizierung müsste wohl ein post sein. Ich würde es erst einmal ohne cors versuchen. bzw. mit Postman. Wenn der Login klappt, kann man immer noch weiter sehen. Mit cors musst du noch extra Header im FE setzen.


   Profil
Lucky_7
Aktiv Letzter Besuch: in der letzten Woche
Dabei seit: 21.01.2018
Mitteilungen: 204
  Beitrag No.10, vom Themenstarter, eingetragen 2021-11-17

wie sich herausstellt, war mein Verständnis ziemlich daneben: Ich hatte sowohl eine Client- als auch eine Server-Applikation geschrieben. Eigentlich benötige ich nur den Server, mein Browser ist ja mein Client. Wenn ich also nur den Server starte und in meinem Browser http://localhost:8080 eingebe, den Controller so erweitere, dass ein Get-Request auf /login mit der login.html antwortet, dann funktioniert alles einwandfrei. Das einzige, was mich noch stört ist, dass ich über meinen gesamten Bildschirm im Hintergrund ein Bild zeige, was zu langsam lädt. Kann man das beschleunigen? Oder dafür sorgen, dass mein Login-Formular auch erst dann sichtbar wird, wenn das Hintergrundbild geladen ist?


   Profil
Lucky_7 hat die Antworten auf ihre/seine Frage gesehen.
Lucky_7 hat selbst das Ok-Häkchen gesetzt.

Wechsel in ein anderes Forum:
 Suchen    
 
All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest © 2001-2022 by Matroids Matheplanet
This web site was originally made with PHP-Nuke, a former web portal system written in PHP that seems no longer to be maintained nor supported. PHP-Nuke is Free Software released under the GNU/GPL license.
Ich distanziere mich von rechtswidrigen oder anstößigen Inhalten, die sich trotz aufmerksamer Prüfung hinter hier verwendeten Links verbergen mögen.
Lesen Sie die Nutzungsbedingungen, die Distanzierung, die Datenschutzerklärung und das Impressum.
[Seitenanfang]