ADD:added decode jwt token and automated login to dashboard after login
This commit is contained in:
@@ -24,7 +24,7 @@ func LoginHandler(c *gin.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Systemnutzer
|
// Systemnutzer
|
||||||
if req.Email == "systemuser@example.com" {
|
if req.Email == "test@localhost.de" {
|
||||||
token, err := CreateJWT("system-user-id", req.Email, "admin", time.Hour*24*7)
|
token, err := CreateJWT("system-user-id", req.Email, "admin", time.Hour*24*7)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.JSON(http.StatusInternalServerError, gin.H{"error": "Token error"})
|
c.JSON(http.StatusInternalServerError, gin.H{"error": "Token error"})
|
||||||
|
|||||||
9
frontend/package-lock.json
generated
9
frontend/package-lock.json
generated
@@ -17,6 +17,7 @@
|
|||||||
"@types/react": "^19.1.4",
|
"@types/react": "^19.1.4",
|
||||||
"@types/react-dom": "^19.1.5",
|
"@types/react-dom": "^19.1.5",
|
||||||
"axios": "^1.9.0",
|
"axios": "^1.9.0",
|
||||||
|
"jwt-decode": "^4.0.0",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
"react-dom": "^19.1.0",
|
"react-dom": "^19.1.0",
|
||||||
"react-router-dom": "^7.6.0",
|
"react-router-dom": "^7.6.0",
|
||||||
@@ -10257,6 +10258,14 @@
|
|||||||
"node": ">=4.0"
|
"node": ">=4.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/jwt-decode": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/jwt-decode/-/jwt-decode-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-+KJGIyHgkGuIq3IEBNftfhW/LfWhXUIY6OmyVWjliu5KH1y0fw7VQ8YndE2O4qZdMSd9SqbnC8GOcZEy0Om7sA==",
|
||||||
|
"engines": {
|
||||||
|
"node": ">=18"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/keyv": {
|
"node_modules/keyv": {
|
||||||
"version": "4.5.4",
|
"version": "4.5.4",
|
||||||
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
"resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz",
|
||||||
|
|||||||
@@ -12,6 +12,7 @@
|
|||||||
"@types/react": "^19.1.4",
|
"@types/react": "^19.1.4",
|
||||||
"@types/react-dom": "^19.1.5",
|
"@types/react-dom": "^19.1.5",
|
||||||
"axios": "^1.9.0",
|
"axios": "^1.9.0",
|
||||||
|
"jwt-decode": "^4.0.0",
|
||||||
"react": "^19.1.0",
|
"react": "^19.1.0",
|
||||||
"react-dom": "^19.1.0",
|
"react-dom": "^19.1.0",
|
||||||
"react-router-dom": "^7.6.0",
|
"react-router-dom": "^7.6.0",
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import Players from './pages/Players';
|
|||||||
import Navigation from './pages/Navigation';
|
import Navigation from './pages/Navigation';
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<AuthProvider>
|
<AuthProvider>
|
||||||
<Router>
|
<Router>
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import React, { createContext, useContext, useState, useEffect } from 'react';
|
|||||||
interface AuthContextType {
|
interface AuthContextType {
|
||||||
token: string | null;
|
token: string | null;
|
||||||
userId: string | null;
|
userId: string | null;
|
||||||
login: (token: string, userId: string) => void;
|
login: (token: string, userId: string, role: string) => void;
|
||||||
logout: () => void;
|
logout: () => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -12,6 +12,7 @@ const AuthContext = createContext<AuthContextType | undefined>(undefined);
|
|||||||
export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
|
||||||
const [token, setToken] = useState<string | null>(null);
|
const [token, setToken] = useState<string | null>(null);
|
||||||
const [userId, setUserId] = useState<string | null>(null);
|
const [userId, setUserId] = useState<string | null>(null);
|
||||||
|
const [role, setRole] = useState<string | null>(null);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const storedToken = localStorage.getItem('token');
|
const storedToken = localStorage.getItem('token');
|
||||||
@@ -22,18 +23,22 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
|||||||
}
|
}
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const login = (token: string, userId: string) => {
|
const login = (token: string, userId: string, role: string) => {
|
||||||
setToken(token);
|
setToken(token);
|
||||||
setUserId(userId);
|
setUserId(userId);
|
||||||
|
setRole(role);
|
||||||
localStorage.setItem('token', token);
|
localStorage.setItem('token', token);
|
||||||
localStorage.setItem('userId', userId);
|
localStorage.setItem('userId', userId);
|
||||||
|
localStorage.setItem('role', role);
|
||||||
};
|
};
|
||||||
|
|
||||||
const logout = () => {
|
const logout = () => {
|
||||||
setToken(null);
|
setToken(null);
|
||||||
setUserId(null);
|
setUserId(null);
|
||||||
|
setRole(null);
|
||||||
localStorage.removeItem('token');
|
localStorage.removeItem('token');
|
||||||
localStorage.removeItem('userId');
|
localStorage.removeItem('userId');
|
||||||
|
localStorage.removeItem('role');
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@@ -43,6 +48,15 @@ export const AuthProvider: React.FC<{ children: React.ReactNode }> = ({ children
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Custom React hook to access the authentication context.
|
||||||
|
*
|
||||||
|
* @returns {AuthContextType} The current authentication context value.
|
||||||
|
* @throws {Error} If used outside of an `AuthProvider`.
|
||||||
|
*
|
||||||
|
* @example
|
||||||
|
* const { user, login, logout } = useAuth();
|
||||||
|
*/
|
||||||
export function useAuth() {
|
export function useAuth() {
|
||||||
const context = useContext(AuthContext);
|
const context = useContext(AuthContext);
|
||||||
if (!context) throw new Error('useAuth must be used within AuthProvider');
|
if (!context) throw new Error('useAuth must be used within AuthProvider');
|
||||||
|
|||||||
@@ -1,22 +1,35 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useAuth } from './AuthContext';
|
import { useAuth } from './AuthContext';
|
||||||
import { login as apiLogin } from './api';
|
import { login as apiLogin } from './api';
|
||||||
|
import { jwtDecode } from 'jwt-decode';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
|
||||||
export default function LoginPage() {
|
export default function LoginPage() {
|
||||||
const { login } = useAuth();
|
const { login } = useAuth();
|
||||||
const [email, setEmail] = useState('');
|
const [email, setEmail] = useState('');
|
||||||
const [password, setPassword] = useState('');
|
const [password, setPassword] = useState('');
|
||||||
const [error, setError] = useState<string | null>(null);
|
const [error, setError] = useState<string | null>(null);
|
||||||
|
const navigate = useNavigate(); // ← Navigation-Hook
|
||||||
|
|
||||||
|
|
||||||
async function handleSubmit(e: React.FormEvent) {
|
async function handleSubmit(e: React.FormEvent) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
try {
|
try {
|
||||||
const data = await apiLogin(email, password);
|
const data = await apiLogin(email, password);
|
||||||
console.log(data);
|
|
||||||
// Token aus JWT extrahieren (hier: UserID im Token Payload)
|
// Token aus JWT extrahieren (hier: UserID im Token Payload)
|
||||||
// Für Demo: Einfach Dummy UserID setzen, oder später JWT decode implementieren
|
// Für Demo: Einfach Dummy UserID setzen, oder später JWT decode implementieren
|
||||||
login(data.token, 'user-id-from-token');
|
type MyJwtPayload = {
|
||||||
} catch {
|
userId: string
|
||||||
|
email: string;
|
||||||
|
role: string;
|
||||||
|
} & object;
|
||||||
|
const decodedData = jwtDecode<MyJwtPayload>(data.token);
|
||||||
|
login(data.token, decodedData.userId, decodedData.role);
|
||||||
|
// Nach dem Login zur Dashboard-Seite navigieren
|
||||||
|
setTimeout(() => {
|
||||||
|
navigate('/');
|
||||||
|
}, 1000);
|
||||||
|
} catch {
|
||||||
setError('Login fehlgeschlagen');
|
setError('Login fehlgeschlagen');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user