diff --git a/growbros-frontend/src/App.tsx b/growbros-frontend/src/App.tsx index ca552f03584ebdd8c63840df0948c915b6ab7c3b..2e7acd837b6f56bd2ea23654ae9714001507f5f1 100644 --- a/growbros-frontend/src/App.tsx +++ b/growbros-frontend/src/App.tsx @@ -2,61 +2,23 @@ import "./App.css"; import Home from "./pages/Home"; import Garten from "./pages/Garten"; import Suche from "./pages/Suche"; -import {Routes, Route, useLocation} from "react-router-dom"; +import {Routes, Route} from "react-router-dom"; import Wunschliste from "./pages/Wunschliste"; import PlantDetails from "./components/PlantDetails"; import Navbar from "./components/Navbar.tsx"; import NavbarRegistrationAndLogin from "./components/NavbarRegistrationAndLogin.tsx"; -import {useEffect, useState} from "react"; -import {deleteJwtInCookie, getCookie} from "./jwt/Cookies.ts"; +import {useState} from "react"; +import {checkJwtStatus, deleteJwtCookie} from "./jwt/Cookies.ts"; import Login from "./pages/Login.tsx"; import Register from "./pages/Register.tsx"; function App() { const [isLoggedIn, setIsLoggedIn] = useState(false); - const location = useLocation(); - useEffect(() => { - console.log("check jwt-status") - const jwtCookie = getCookie("Jwt"); - console.log("Jwt Cookie " + jwtCookie) - - if (!jwtCookie) { - // Wenn der JWT-Cookie nicht vorhanden ist - setIsLoggedIn(false); - console.log("Jwt not there") - return; - } - - // Der JWT-Cookie ist vorhanden - Überprüfe die Gültigkeit - // @ts-ignore - const tokenParts = jwtCookie.split('.'); - if (tokenParts.length !== 3) { - // Ungültiges JWT-Format (nicht genau 3 Teile) - setIsLoggedIn(false); - console.log("Jwt is not valid") - return; - } - - const payload = JSON.parse(atob(tokenParts[1])); - const expirationTime = payload.exp * 1000; //Umwandlung in Millisekunden - console.log(expirationTime) - console.log(Date.now()) - - // Überprüfe das Ablaufdatum - if (Date.now() > expirationTime) { - // JWT ist abgelaufen - setIsLoggedIn(false); - console.log("Jwt is expired") - return; - } - console.log("Token is there and valid") - // JWT ist vorhanden und gültig - setIsLoggedIn(true); - }, [location.pathname]); + checkJwtStatus(setIsLoggedIn); const handleLogout = async () => { - deleteJwtInCookie(); + deleteJwtCookie(); setIsLoggedIn(false); }; diff --git a/growbros-frontend/src/jwt/Cookies.ts b/growbros-frontend/src/jwt/Cookies.ts index 91f4f00b2dcf25264d2d222254a1b1dea929cd19..54ff1341cc9011536bdf7259559541ef920e4d62 100644 --- a/growbros-frontend/src/jwt/Cookies.ts +++ b/growbros-frontend/src/jwt/Cookies.ts @@ -1,8 +1,12 @@ -export function setCookie(name: string, value: any, expirationDate: Date){ +import {useLocation} from "react-router-dom"; +import {SetStateAction, useEffect} from "react"; + +export function setCookie(name: string, value: any, expirationDate: Date) { let expires = "expires=" + expirationDate; document.cookie = `${name}=${value}; ${expires}` } -export function getCookie(name: string | any[]){ + +export function getCookie(name: string | any[]) { const cDecoded = decodeURIComponent(document.cookie); const cArray = cDecoded.split("; "); @@ -10,14 +14,59 @@ export function getCookie(name: string | any[]){ cArray.forEach(element => { - if(element.indexOf(<string>name) == 0){ + if (element.indexOf(<string>name) == 0) { result = element.substring(name.length + 1) } }) return result; } -export function deleteJwtInCookie(){ + +export function deleteJwtCookie() { document.cookie = `Jwt=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;`; console.log("deleted Cookie ") } + +export function checkJwtStatus(setIsLoggedIn: { (value: SetStateAction<boolean>): void; (arg0: boolean): void; }) { + const location = useLocation(); + + return useEffect(() => { + console.log("check jwt-status") + const jwtCookie = getCookie("Jwt"); + console.log("Jwt Cookie " + jwtCookie) + + if (!jwtCookie) { + // Wenn der JWT-Cookie nicht vorhanden ist + setIsLoggedIn(false); + console.log("Jwt not there") + return; + } + + // Der JWT-Cookie ist vorhanden - Überprüfe die Gültigkeit + // @ts-ignore + const tokenParts = jwtCookie.split('.'); + if (tokenParts.length !== 3) { + // Ungültiges JWT-Format (nicht genau 3 Teile) + setIsLoggedIn(false); + console.log("Jwt is not valid") + return; + } + + const payload = JSON.parse(atob(tokenParts[1])); + const expirationTime = payload.exp * 1000; //Umwandlung in Millisekunden + console.log(expirationTime) + console.log(Date.now()) + + // Überprüfe das Ablaufdatum + if (Date.now() > expirationTime) { + // JWT ist abgelaufen + setIsLoggedIn(false); + console.log("Jwt is expired") + return; + } + console.log("Token is there and valid") + // JWT ist vorhanden und gültig + setIsLoggedIn(true); + }, [location.pathname]); + +} diff --git a/growbros-frontend/src/pages/Login.tsx b/growbros-frontend/src/pages/Login.tsx index b30ef8d2885b45f5766e9175264300c67dc21f9e..bca3ce7cf6ed933c688b308de205ce4931bad1b3 100644 --- a/growbros-frontend/src/pages/Login.tsx +++ b/growbros-frontend/src/pages/Login.tsx @@ -1,7 +1,12 @@ import {useState} from "react"; -import {setCookie} from "../jwt/Cookies.ts"; +import {deleteJwtCookie, setCookie} from "../jwt/Cookies.ts"; +import {jwtDecode} from "jwt-decode"; +import {useNavigate} from "react-router-dom"; function Login() { + + const navigate = useNavigate(); + const [email, setEmail] = useState(''); const [password, setPassword] = useState(''); @@ -11,10 +16,32 @@ function Login() { }; const handleLogin = async () => { try { - const res = await fetch("http://localhost:8080/api/v1/auth/authenticate",{method:"POST",body:JSON.stringify({email:email,password:password})}) - const {token} = await res.json(); - setCookie("Jwt",token, 1); - console.log(token); + const res = await fetch("http://localhost:8080/api/v1/auth/authenticate",{ + method:"POST", + body:JSON.stringify({email:email,password:password}), + headers: { + "Content-Type": "application/json", + }, + }); + if (res.ok) { //delete old cookie and set new one with new expiration date + const { token } = await res.json(); + console.log(token); + deleteJwtCookie(); + const decodedToken = jwtDecode(token); + console.log(decodedToken); + // @ts-ignore + const expirationDate = new Date(decodedToken.exp * 1000); //*1000 Anzahl der Sekunden seit 1.1.1970 darstellt - JS arbeitet jedoch normalerweise mit Millisekunden + setCookie("Jwt",token, expirationDate); + document.cookie = `Jwt=${token};expires=${new Date(expirationDate).toUTCString()};path=/;`; + + navigate('/'); + + } else { + window.alert(`Fehler bei der Anmeldung: ${res.status} - ${res.statusText}`); + navigate('/login'); + console.error('Fehler bei der Anmeldung:', res.status, res.statusText); + } + } catch (error:any) { console.error('Fehler bei der Anmeldung:', error.message); } @@ -24,9 +51,9 @@ function Login() { <main> <div> <h2>Login</h2> - <form> + <form onSubmit={handleSubmit}> <div> - <label>Benutzername oder E-Mail:</label> + <label>E-Mail:</label> <input type="text" value={email} @@ -42,9 +69,7 @@ function Login() { /> </div> <div> - <form onSubmit={handleSubmit}> <button type="submit">Anmelden</button> - </form> </div> </form> </div> diff --git a/src/main/java/hdm/mi/growbros/auth/AuthenticationService.java b/src/main/java/hdm/mi/growbros/auth/AuthenticationService.java index acecf64d1eda1e83d56ab87035757732a12c1b44..9cba3736e0de8b1adadc8ddd73b2a57a6fd31ec1 100644 --- a/src/main/java/hdm/mi/growbros/auth/AuthenticationService.java +++ b/src/main/java/hdm/mi/growbros/auth/AuthenticationService.java @@ -46,7 +46,8 @@ public class AuthenticationService { ) ); var user = repository.findByEmail(request.getEmail()) //wenn der Nutzername und Passwort korrekt sind wird ein Token generiert - .orElseThrow(); + .orElseThrow(); // = Methode von Optional -> wird auf das Optionale angewendet, das durch repository.findByEmail zurückgegeben wird + // Wenn Benutzer gefunden -> das Optional mit dem Benutzer-Objekt gefüllt. Andernfalls wird eine NoSuchElementException ausgelöst. var jwtToken = jwtService.generateToken(user); return AuthenticationResponse.builder() .token(jwtToken) diff --git a/src/main/java/hdm/mi/growbros/security/ApplicationConfig.java b/src/main/java/hdm/mi/growbros/security/ApplicationConfig.java index 5c2d13d458f73fb73036cc4e6dda1831e4b7dc0d..cdcfea21e3eea3034feaa74ce26c54c11afa49f9 100644 --- a/src/main/java/hdm/mi/growbros/security/ApplicationConfig.java +++ b/src/main/java/hdm/mi/growbros/security/ApplicationConfig.java @@ -17,16 +17,12 @@ import org.springframework.security.crypto.password.PasswordEncoder; @RequiredArgsConstructor public class ApplicationConfig { private final UserRepository repository; - @Bean + @Bean //Schnittstelle die verwendet wird, um Benutzerdetails zu laden public UserDetailsService userDetailsService() { return username -> repository.findByEmail(username) .orElseThrow(() -> new UsernameNotFoundException("User not found")); } - /** - * Fetcht die Benutzer Daten und decodiert das Passwort. - * @return - */ @Bean public AuthenticationProvider authenticationProvider() { DaoAuthenticationProvider authProvider = new DaoAuthenticationProvider(); diff --git a/src/main/java/hdm/mi/growbros/security/SecurityConfiguration.java b/src/main/java/hdm/mi/growbros/security/SecurityConfiguration.java index 3adcd66aa873cc3abd4760e0322aa21bf6b379dd..ccabf85d11ce17357187463ef80f6738915ddb7e 100644 --- a/src/main/java/hdm/mi/growbros/security/SecurityConfiguration.java +++ b/src/main/java/hdm/mi/growbros/security/SecurityConfiguration.java @@ -29,7 +29,7 @@ public class SecurityConfiguration { public SecurityFilterChain securityFilterChain(HttpSecurity http, MvcRequestMatcher.Builder mvc) throws Exception { http .csrf(csrf -> { - csrf.disable(); + csrf.disable(); //CSRF-Schutz deaktivieren csrf.ignoringRequestMatchers(toH2Console()); }) .authorizeHttpRequests((authorize) -> //whitelist