mirror of
https://git.v0id.ovh/n3wt-innov/n3wt-school.git
synced 2026-01-29 07:53:23 +00:00
feat: Suite de la gestion des sessions
This commit is contained in:
@ -148,8 +148,7 @@ class ProfileSimpleView(APIView):
|
|||||||
def delete(self, request, id):
|
def delete(self, request, id):
|
||||||
return bdd.delete_object(Profile, id)
|
return bdd.delete_object(Profile, id)
|
||||||
|
|
||||||
@method_decorator(csrf_protect, name='dispatch')
|
@method_decorator(csrf_exempt, name='dispatch')
|
||||||
@method_decorator(ensure_csrf_cookie, name='dispatch')
|
|
||||||
class LoginView(APIView):
|
class LoginView(APIView):
|
||||||
@swagger_auto_schema(
|
@swagger_auto_schema(
|
||||||
operation_description="Connexion utilisateur",
|
operation_description="Connexion utilisateur",
|
||||||
@ -168,7 +167,8 @@ class LoginView(APIView):
|
|||||||
'errorFields': openapi.Schema(type=openapi.TYPE_OBJECT),
|
'errorFields': openapi.Schema(type=openapi.TYPE_OBJECT),
|
||||||
'errorMessage': openapi.Schema(type=openapi.TYPE_STRING),
|
'errorMessage': openapi.Schema(type=openapi.TYPE_STRING),
|
||||||
'profil': openapi.Schema(type=openapi.TYPE_INTEGER),
|
'profil': openapi.Schema(type=openapi.TYPE_INTEGER),
|
||||||
'droit': openapi.Schema(type=openapi.TYPE_INTEGER)
|
'droit': openapi.Schema(type=openapi.TYPE_INTEGER),
|
||||||
|
'id': openapi.Schema(type=openapi.TYPE_INTEGER),
|
||||||
}
|
}
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -196,13 +196,12 @@ class LoginView(APIView):
|
|||||||
else:
|
else:
|
||||||
retour = error.returnMessage[error.WRONG_ID]
|
retour = error.returnMessage[error.WRONG_ID]
|
||||||
|
|
||||||
|
|
||||||
return JsonResponse({
|
return JsonResponse({
|
||||||
'errorFields': errorFields,
|
'errorFields': errorFields,
|
||||||
'errorMessage': retour,
|
'errorMessage': retour,
|
||||||
'profil': user.id if user else -1,
|
'profil': user.id if user else -1,
|
||||||
'droit': user.droit if user else -1,
|
'droit': user.droit if user else -1,
|
||||||
#'jwtToken':jwt_token if profil != -1 else ''
|
'id': user.id if user else -1,
|
||||||
}, safe=False)
|
}, safe=False)
|
||||||
|
|
||||||
@method_decorator(csrf_protect, name='dispatch')
|
@method_decorator(csrf_protect, name='dispatch')
|
||||||
|
|||||||
@ -252,19 +252,10 @@ CORS_ALLOW_ALL_HEADERS = True
|
|||||||
CORS_ALLOW_CREDENTIALS = True
|
CORS_ALLOW_CREDENTIALS = True
|
||||||
|
|
||||||
CORS_ALLOWED_ORIGINS = [
|
CORS_ALLOWED_ORIGINS = [
|
||||||
'http://localhost:3000'
|
os.getenv('CORS_ALLOWED_ORIGINS', 'http://localhost:3000')
|
||||||
]
|
]
|
||||||
|
|
||||||
CSRF_TRUSTED_ORIGINS = [
|
CSRF_TRUSTED_ORIGINS = os.getenv('CSRF_TRUSTED_ORIGINS', 'http://localhost:3000,http://localhost:8080').split(',')
|
||||||
'http://localhost:3000',
|
|
||||||
'http://localhost:8080'
|
|
||||||
]
|
|
||||||
|
|
||||||
# CORS_ALLOWED_ORIGINS = [
|
|
||||||
# os.getenv('CORS_ALLOWED_ORIGINS', 'http://localhost:3000')
|
|
||||||
# ]
|
|
||||||
|
|
||||||
# CSRF_TRUSTED_ORIGINS = os.getenv('CSRF_TRUSTED_ORIGINS', 'http://localhost:3000,http://localhost:8080').split(',')
|
|
||||||
|
|
||||||
CSRF_COOKIE_HTTPONLY = False
|
CSRF_COOKIE_HTTPONLY = False
|
||||||
CSRF_COOKIE_SECURE = False
|
CSRF_COOKIE_SECURE = False
|
||||||
|
|||||||
@ -26,6 +26,8 @@ import {
|
|||||||
|
|
||||||
import { disconnect } from '@/app/lib/authAction';
|
import { disconnect } from '@/app/lib/authAction';
|
||||||
import { fetchEstablishment } from '@/app/lib/schoolAction';
|
import { fetchEstablishment } from '@/app/lib/schoolAction';
|
||||||
|
import ProtectedRoute from '@/components/ProtectedRoute';
|
||||||
|
import { SessionProvider } from 'next-auth/react';
|
||||||
|
|
||||||
export default function Layout({
|
export default function Layout({
|
||||||
children,
|
children,
|
||||||
@ -73,6 +75,9 @@ export default function Layout({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
|
||||||
|
<SessionProvider>
|
||||||
|
<ProtectedRoute>
|
||||||
{!isLoading && (
|
{!isLoading && (
|
||||||
<div className="flex min-h-screen bg-gray-50">
|
<div className="flex min-h-screen bg-gray-50">
|
||||||
<Sidebar establishment={establishment} currentPage={currentPage} items={Object.values(sidebarItems)} className="h-full" />
|
<Sidebar establishment={establishment} currentPage={currentPage} items={Object.values(sidebarItems)} className="h-full" />
|
||||||
@ -105,6 +110,9 @@ export default function Layout({
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
|
</ProtectedRoute>
|
||||||
|
</SessionProvider>
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -4,7 +4,7 @@ import StructureManagement from '@/components/Structure/Configuration/StructureM
|
|||||||
import ScheduleManagement from '@/components/Structure/Planning/ScheduleManagement';
|
import ScheduleManagement from '@/components/Structure/Planning/ScheduleManagement';
|
||||||
import FeesManagement from '@/components/Structure/Tarification/FeesManagement';
|
import FeesManagement from '@/components/Structure/Tarification/FeesManagement';
|
||||||
import DjangoCSRFToken from '@/components/DjangoCSRFToken';
|
import DjangoCSRFToken from '@/components/DjangoCSRFToken';
|
||||||
import useCsrfToken from '@/hooks/useCsrfToken';
|
import { useCsrfToken } from '@/context/CsrfContext';
|
||||||
import { ClassesProvider } from '@/context/ClassesContext';
|
import { ClassesProvider } from '@/context/ClassesContext';
|
||||||
import { createDatas,
|
import { createDatas,
|
||||||
updateDatas,
|
updateDatas,
|
||||||
|
|||||||
@ -3,7 +3,7 @@ import React, { useState, useEffect } from 'react';
|
|||||||
import { useSearchParams, useRouter } from 'next/navigation';
|
import { useSearchParams, useRouter } from 'next/navigation';
|
||||||
import InscriptionFormShared from '@/components/Inscription/InscriptionFormShared';
|
import InscriptionFormShared from '@/components/Inscription/InscriptionFormShared';
|
||||||
import { FE_ADMIN_SUBSCRIPTIONS_URL } from '@/utils/Url';
|
import { FE_ADMIN_SUBSCRIPTIONS_URL } from '@/utils/Url';
|
||||||
import useCsrfToken from '@/hooks/useCsrfToken';
|
import { useCsrfToken } from '@/context/CsrfContext';
|
||||||
import { mockStudent } from '@/data/mockStudent';
|
import { mockStudent } from '@/data/mockStudent';
|
||||||
import { editRegisterForm, fetchRegisterForm } from '@/app/lib/subscriptionAction';
|
import { editRegisterForm, fetchRegisterForm } from '@/app/lib/subscriptionAction';
|
||||||
|
|
||||||
|
|||||||
@ -42,7 +42,7 @@ import {
|
|||||||
FE_ADMIN_SUBSCRIPTIONS_EDIT_URL } from '@/utils/Url';
|
FE_ADMIN_SUBSCRIPTIONS_EDIT_URL } from '@/utils/Url';
|
||||||
|
|
||||||
import DjangoCSRFToken from '@/components/DjangoCSRFToken'
|
import DjangoCSRFToken from '@/components/DjangoCSRFToken'
|
||||||
import useCsrfToken from '@/hooks/useCsrfToken';
|
import { useCsrfToken } from '@/context/CsrfContext';
|
||||||
import { fetchRegistrationFileGroups } from '@/app/lib/registerFileGroupAction';
|
import { fetchRegistrationFileGroups } from '@/app/lib/registerFileGroupAction';
|
||||||
|
|
||||||
const useFakeData = process.env.NEXT_PUBLIC_USE_FAKE_DATA === 'true';
|
const useFakeData = process.env.NEXT_PUBLIC_USE_FAKE_DATA === 'true';
|
||||||
|
|||||||
@ -2,7 +2,7 @@
|
|||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import InscriptionFormShared from '@/components/Inscription/InscriptionFormShared';
|
import InscriptionFormShared from '@/components/Inscription/InscriptionFormShared';
|
||||||
import { useSearchParams, useRouter } from 'next/navigation';
|
import { useSearchParams, useRouter } from 'next/navigation';
|
||||||
import useCsrfToken from '@/hooks/useCsrfToken';
|
import { useCsrfToken } from '@/context/CsrfContext';
|
||||||
import { FE_PARENTS_HOME_URL} from '@/utils/Url';
|
import { FE_PARENTS_HOME_URL} from '@/utils/Url';
|
||||||
import { editRegisterForm} from '@/app/lib/subscriptionAction';
|
import { editRegisterForm} from '@/app/lib/subscriptionAction';
|
||||||
|
|
||||||
|
|||||||
@ -9,9 +9,12 @@ import Button from '@/components/Button'; // Importez le composant Button
|
|||||||
import { User, KeySquare } from 'lucide-react'; // Importez directement les icônes nécessaires
|
import { User, KeySquare } from 'lucide-react'; // Importez directement les icônes nécessaires
|
||||||
import {
|
import {
|
||||||
FE_USERS_NEW_PASSWORD_URL,
|
FE_USERS_NEW_PASSWORD_URL,
|
||||||
BE_AUTH_INFO_SESSION } from '@/utils/Url';
|
BE_AUTH_INFO_SESSION,
|
||||||
|
FE_ADMIN_SUBSCRIPTIONS_URL,
|
||||||
|
FE_PARENTS_HOME_URL
|
||||||
|
} from '@/utils/Url';
|
||||||
import useLocalStorage from '@/hooks/useLocalStorage';
|
import useLocalStorage from '@/hooks/useLocalStorage';
|
||||||
import { signIn } from 'next-auth/react';
|
import { signIn, getSession } from 'next-auth/react';
|
||||||
import { useCsrfToken } from '@/context/CsrfContext'; // Importez le hook useCsrfToken
|
import { useCsrfToken } from '@/context/CsrfContext'; // Importez le hook useCsrfToken
|
||||||
|
|
||||||
const useFakeData = process.env.NEXT_PUBLIC_USE_FAKE_DATA === 'true';
|
const useFakeData = process.env.NEXT_PUBLIC_USE_FAKE_DATA === 'true';
|
||||||
@ -33,32 +36,46 @@ export default function Page() {
|
|||||||
return data.errorMessage === ""
|
return data.errorMessage === ""
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleFormLogin(formData) {
|
async function handleFormLogin(formData) {
|
||||||
setIsLoading(true);
|
setIsLoading(true);
|
||||||
console.log('Form Data', Object.fromEntries(formData.entries())); // Affichez les entrées du FormData
|
|
||||||
console.log('csrf passé ', csrfToken); // Affichez le token CSRF
|
|
||||||
|
|
||||||
signIn('credentials', {
|
try {
|
||||||
|
const result = await signIn('credentials', {
|
||||||
redirect: false,
|
redirect: false,
|
||||||
email: formData.get('login'),
|
email: formData.get('login'),
|
||||||
password: formData.get('password'),
|
password: formData.get('password'),
|
||||||
csrfToken: csrfToken // Utilisez le token CSRF récupéré par le hook
|
});
|
||||||
})
|
|
||||||
.then(result => {
|
|
||||||
console.log('Sign In Result', result);
|
console.log('Sign In Result', result);
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
|
|
||||||
if (result.error) {
|
if (result.error) {
|
||||||
setErrorMessage(result.error);
|
setErrorMessage(result.error);
|
||||||
} else {
|
} else {
|
||||||
router.push(result.url);
|
const session = await getSession();
|
||||||
|
if (!session || !session.user) {
|
||||||
|
throw new Error('Session not found');
|
||||||
}
|
}
|
||||||
})
|
const user = session.user;
|
||||||
.catch(error => {
|
console.log('User Session:', user);
|
||||||
|
localStorage.setItem('userId', user.id); // Stocker l'identifiant de l'utilisateur
|
||||||
|
if (user.droit === 0) {
|
||||||
|
// Vue ECOLE
|
||||||
|
} else if (user.droit === 1) {
|
||||||
|
// Vue ADMIN
|
||||||
|
router.push(FE_ADMIN_SUBSCRIPTIONS_URL);
|
||||||
|
} else if (user.droit === 2) {
|
||||||
|
// Vue PARENT
|
||||||
|
router.push(FE_PARENTS_HOME_URL);
|
||||||
|
} else {
|
||||||
|
// Cas anormal
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
console.error('Error during sign in:', error);
|
console.error('Error during sign in:', error);
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
setErrorMessage('An error occurred during sign in.');
|
setErrorMessage('An error occurred during sign in.');
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isLoading === true) {
|
if (isLoading === true) {
|
||||||
|
|||||||
@ -10,7 +10,7 @@ import Button from '@/components/Button'; // Importez le composant Button
|
|||||||
import Popup from '@/components/Popup'; // Importez le composant Popup
|
import Popup from '@/components/Popup'; // Importez le composant Popup
|
||||||
import { User } from 'lucide-react'; // Importez directement les icônes nécessaires
|
import { User } from 'lucide-react'; // Importez directement les icônes nécessaires
|
||||||
import { FE_USERS_LOGIN_URL } from '@/utils/Url';
|
import { FE_USERS_LOGIN_URL } from '@/utils/Url';
|
||||||
import useCsrfToken from '@/hooks/useCsrfToken';
|
import { useCsrfToken } from '@/context/CsrfContext';
|
||||||
import { sendNewPassword } from '@/app/lib/authAction';
|
import { sendNewPassword } from '@/app/lib/authAction';
|
||||||
|
|
||||||
const useFakeData = process.env.NEXT_PUBLIC_USE_FAKE_DATA === 'true';
|
const useFakeData = process.env.NEXT_PUBLIC_USE_FAKE_DATA === 'true';
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import Button from '@/components/Button'; // Importez le composant Button
|
|||||||
import Popup from '@/components/Popup';
|
import Popup from '@/components/Popup';
|
||||||
import { FE_USERS_LOGIN_URL } from '@/utils/Url';
|
import { FE_USERS_LOGIN_URL } from '@/utils/Url';
|
||||||
import { KeySquare } from 'lucide-react'; // Importez directement les icônes nécessaires
|
import { KeySquare } from 'lucide-react'; // Importez directement les icônes nécessaires
|
||||||
import useCsrfToken from '@/hooks/useCsrfToken';
|
import { useCsrfToken } from '@/context/CsrfContext';
|
||||||
import { getResetPassword, resetPassword } from '@/app/lib/authAction';
|
import { getResetPassword, resetPassword } from '@/app/lib/authAction';
|
||||||
|
|
||||||
const useFakeData = process.env.NEXT_PUBLIC_USE_FAKE_DATA === 'true';
|
const useFakeData = process.env.NEXT_PUBLIC_USE_FAKE_DATA === 'true';
|
||||||
|
|||||||
@ -11,7 +11,7 @@ import Button from '@/components/Button'; // Importez le composant Button
|
|||||||
import Popup from '@/components/Popup'; // Importez le composant Popup
|
import Popup from '@/components/Popup'; // Importez le composant Popup
|
||||||
import { User, KeySquare } from 'lucide-react'; // Importez directement les icônes nécessaires
|
import { User, KeySquare } from 'lucide-react'; // Importez directement les icônes nécessaires
|
||||||
import { FE_USERS_LOGIN_URL } from '@/utils/Url';
|
import { FE_USERS_LOGIN_URL } from '@/utils/Url';
|
||||||
import useCsrfToken from '@/hooks/useCsrfToken';
|
import { useCsrfToken } from '@/context/CsrfContext';
|
||||||
import { subscribe } from '@/app/lib/authAction';
|
import { subscribe } from '@/app/lib/authAction';
|
||||||
const useFakeData = process.env.NEXT_PUBLIC_USE_FAKE_DATA === 'true';
|
const useFakeData = process.env.NEXT_PUBLIC_USE_FAKE_DATA === 'true';
|
||||||
|
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { NextIntlClientProvider } from 'next-intl';
|
|
||||||
import { CsrfProvider } from '@/context/CsrfContext'; // Importez le CsrfProvider
|
|
||||||
|
|
||||||
import { getMessages } from 'next-intl/server';
|
import { getMessages } from 'next-intl/server';
|
||||||
|
import { NextIntlClientProvider } from 'next-intl';
|
||||||
|
import { CsrfProvider } from '@/context/CsrfContext';
|
||||||
import "@/css/tailwind.css";
|
import "@/css/tailwind.css";
|
||||||
|
|
||||||
export const metadata = {
|
export const metadata = {
|
||||||
@ -22,14 +21,15 @@ export const metadata = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
export default async function RootLayout({ children, params: { locale } }) {
|
export default async function RootLayout({ children, params }) {
|
||||||
const messages = await getMessages();
|
const { locale } = params;
|
||||||
|
const messages = await getMessages(locale); // Passez le locale ici
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<html lang={locale}>
|
<html lang={locale}>
|
||||||
<body>
|
<body>
|
||||||
<CsrfProvider> {/* Enveloppez votre application avec le CsrfProvider */}
|
<CsrfProvider>
|
||||||
<NextIntlClientProvider messages={messages}>
|
<NextIntlClientProvider messages={messages} locale={locale}> {/* Passez le locale ici */}
|
||||||
{children}
|
{children}
|
||||||
</NextIntlClientProvider>
|
</NextIntlClientProvider>
|
||||||
</CsrfProvider>
|
</CsrfProvider>
|
||||||
|
|||||||
@ -1,24 +1,27 @@
|
|||||||
import React, { useEffect } from 'react';
|
import React, { useEffect } from 'react';
|
||||||
import { useRouter } from 'next/navigation';
|
import { useRouter } from 'next/navigation';
|
||||||
import useLocalStorage from '@/hooks/useLocalStorage';
|
import { useSession } from 'next-auth/react';
|
||||||
|
import Loader from '@/components/Loader'; // Importez le composant Loader
|
||||||
import { FE_USERS_LOGIN_URL } from '@/utils/Url';
|
import { FE_USERS_LOGIN_URL } from '@/utils/Url';
|
||||||
|
|
||||||
const ProtectedRoute = ({ children }) => {
|
const ProtectedRoute = ({ children }) => {
|
||||||
|
const { data: session, status } = useSession();
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [userId] = useLocalStorage("userId", '');
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!userId) {
|
if (status === 'loading') return; // Ne rien faire tant que le statut est "loading"
|
||||||
|
if (!session) {
|
||||||
// Rediriger vers la page de login si l'utilisateur n'est pas connecté
|
// Rediriger vers la page de login si l'utilisateur n'est pas connecté
|
||||||
router.push(FE_USERS_LOGIN_URL);
|
router.push(`${FE_USERS_LOGIN_URL}`);
|
||||||
}
|
}
|
||||||
}, [userId, router]);
|
}, [session, status, router]);
|
||||||
|
|
||||||
if (!userId) {
|
if (status === 'loading' || !session) {
|
||||||
return <div>Loading...</div>;
|
return <Loader />; // Affichez un loader pendant le chargement ou si l'utilisateur n'est pas connecté
|
||||||
}
|
}
|
||||||
|
|
||||||
// Afficher les enfants seulement si l'utilisateur est connecté
|
// Afficher les enfants seulement si l'utilisateur est connecté
|
||||||
return userId ? children : null;
|
return children;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default ProtectedRoute;
|
export default ProtectedRoute;
|
||||||
@ -4,7 +4,7 @@ import Table from '@/components/Table';
|
|||||||
import Popup from '@/components/Popup';
|
import Popup from '@/components/Popup';
|
||||||
import ToggleSwitch from '@/components/ToggleSwitch';
|
import ToggleSwitch from '@/components/ToggleSwitch';
|
||||||
import { createProfile, updateProfile } from '@/app/lib/authAction';
|
import { createProfile, updateProfile } from '@/app/lib/authAction';
|
||||||
import useCsrfToken from '@/hooks/useCsrfToken';
|
import { useCsrfToken } from '@/context/CsrfContext';
|
||||||
import { DndProvider, useDrag, useDrop } from 'react-dnd';
|
import { DndProvider, useDrag, useDrop } from 'react-dnd';
|
||||||
import { HTML5Backend } from 'react-dnd-html5-backend';
|
import { HTML5Backend } from 'react-dnd-html5-backend';
|
||||||
import InputText from '@/components/InputText';
|
import InputText from '@/components/InputText';
|
||||||
|
|||||||
@ -1,12 +0,0 @@
|
|||||||
import { getCsrfToken } from '@/utils/getCsrfToken';
|
|
||||||
|
|
||||||
export const csrfMiddleware = (handler) => {
|
|
||||||
return async (req, res) => {
|
|
||||||
const csrfToken = getCsrfToken();
|
|
||||||
if (!csrfToken) {
|
|
||||||
console.error('CSRF Token is undefined');
|
|
||||||
}
|
|
||||||
req.csrfToken = csrfToken;
|
|
||||||
return handler(req, res);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
@ -1,29 +0,0 @@
|
|||||||
// import { useEffect, useState } from 'react';
|
|
||||||
// import { BE_AUTH_CSRF_URL } from '@/utils/Url';
|
|
||||||
|
|
||||||
// const useCsrfToken = () => {
|
|
||||||
// const [token, setToken] = useState('');
|
|
||||||
|
|
||||||
// useEffect(() => {
|
|
||||||
// fetch(`${BE_AUTH_CSRF_URL}`, {
|
|
||||||
// method: 'GET',
|
|
||||||
// credentials: 'include' // Inclut les cookies dans la requête
|
|
||||||
// })
|
|
||||||
// .then(response => response.json())
|
|
||||||
// .then(data => {
|
|
||||||
// if (data) {
|
|
||||||
// if(data.csrfToken != token) {
|
|
||||||
// setToken(data.csrfToken);
|
|
||||||
// console.log('------------> CSRF Token reçu:', data.csrfToken);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
// .catch(error => {
|
|
||||||
// console.error('Error fetching CSRF token:', error);
|
|
||||||
// });
|
|
||||||
// }, []);
|
|
||||||
|
|
||||||
// return token;
|
|
||||||
// };
|
|
||||||
|
|
||||||
// export default useCsrfToken;
|
|
||||||
@ -1,7 +1,6 @@
|
|||||||
import NextAuth from 'next-auth';
|
import NextAuth from 'next-auth';
|
||||||
import CredentialsProvider from 'next-auth/providers/credentials';
|
import CredentialsProvider from 'next-auth/providers/credentials';
|
||||||
import jwt from 'jsonwebtoken';
|
import { BE_AUTH_LOGIN_URL } from '@/utils/Url';
|
||||||
import { csrfMiddleware } from '@/csrfMiddleware'; // Importez le middleware csrfMiddleware
|
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
providers: [
|
providers: [
|
||||||
@ -11,43 +10,32 @@ const options = {
|
|||||||
email: { label: 'Email', type: 'email' },
|
email: { label: 'Email', type: 'email' },
|
||||||
password: { label: 'Password', type: 'password' }
|
password: { label: 'Password', type: 'password' }
|
||||||
},
|
},
|
||||||
authorize: (credentials, req) => {
|
authorize: async (credentials, req) => {
|
||||||
console.log('Credentials:', credentials); // Vérifiez si ce log s'affiche
|
const response = await fetch(`${BE_AUTH_LOGIN_URL}`, {
|
||||||
|
|
||||||
// Utilisez le token CSRF injecté par le middleware
|
|
||||||
const csrfToken = req.csrfToken;
|
|
||||||
console.log("data to send : ", JSON.stringify({
|
|
||||||
email: credentials.email,
|
|
||||||
password: credentials.password
|
|
||||||
}), "csrfToken : ", csrfToken);
|
|
||||||
|
|
||||||
return fetch(`${process.env.NEXT_PUBLIC_API_URL}/Auth/login`, {
|
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json',
|
'Content-Type': 'application/json',
|
||||||
'X-CSRFToken': csrfToken // Utiliser le token CSRF ici
|
|
||||||
},
|
},
|
||||||
body: JSON.stringify({
|
body: JSON.stringify({
|
||||||
email: credentials.email,
|
email: credentials.email,
|
||||||
password: credentials.password
|
password: credentials.password
|
||||||
}),
|
}),
|
||||||
credentials: 'include'
|
credentials: 'include'
|
||||||
})
|
});
|
||||||
.then(response => response.text())
|
|
||||||
.then(text => {
|
|
||||||
console.log('Response Text:', text); // Loggez la réponse
|
|
||||||
const user = JSON.parse(text); // Parsez la réponse en JSON
|
|
||||||
|
|
||||||
|
const user = await response.json();
|
||||||
|
|
||||||
|
console.log("API response:", user);
|
||||||
if (response.ok && user) {
|
if (response.ok && user) {
|
||||||
return user;
|
const userData = {
|
||||||
|
id: user.id,
|
||||||
|
role: user.profil,
|
||||||
|
droit: user.droit
|
||||||
|
};
|
||||||
|
return userData;
|
||||||
} else {
|
} else {
|
||||||
throw new Error(user.errorMessage || 'Invalid credentials');
|
throw new Error(user.errorMessage || 'Invalid credentials');
|
||||||
}
|
}
|
||||||
})
|
|
||||||
.catch(error => {
|
|
||||||
console.error('Error during authentication:', error);
|
|
||||||
throw new Error('Authentication failed');
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
],
|
],
|
||||||
@ -55,25 +43,35 @@ const options = {
|
|||||||
jwt: true
|
jwt: true
|
||||||
},
|
},
|
||||||
callbacks: {
|
callbacks: {
|
||||||
async jwt(token, user) {
|
async jwt({ token, user }) {
|
||||||
|
console.log("JWT callback called", user);
|
||||||
if (user) {
|
if (user) {
|
||||||
token.id = user.id;
|
token.id = user.id;
|
||||||
token.email = user.email;
|
|
||||||
token.role = user.role;
|
token.role = user.role;
|
||||||
|
token.droit = user.droit;
|
||||||
}
|
}
|
||||||
return token;
|
return token;
|
||||||
},
|
},
|
||||||
async session(session, token) {
|
async session({ session, token }) {
|
||||||
session.user.id = token.id;
|
console.log("Session callback called", token);
|
||||||
session.user.email = token.email;
|
if (!token) {
|
||||||
session.user.role = token.role;
|
throw new Error('Token not found');
|
||||||
|
}
|
||||||
|
session.user = {
|
||||||
|
id: token.id,
|
||||||
|
role: token.role,
|
||||||
|
droit: token.droit
|
||||||
|
};
|
||||||
return session;
|
return session;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
pages: {
|
pages: {
|
||||||
signIn: '/[locale]/users/login'
|
signIn: '/[locale]/users/login'
|
||||||
},
|
},
|
||||||
csrf: false // Désactiver la gestion CSRF de NextAuth.js
|
csrf: true
|
||||||
};
|
};
|
||||||
|
|
||||||
export default csrfMiddleware((req, res) => NextAuth(req, res, options));
|
export default (req, res) => {
|
||||||
|
console.log("NextAuth handler called");
|
||||||
|
return NextAuth(req, res, options);
|
||||||
|
};
|
||||||
@ -1,42 +0,0 @@
|
|||||||
import { useSession, getSession } from 'next-auth/react';
|
|
||||||
import { useRouter } from 'next/router';
|
|
||||||
import { useEffect } from 'react';
|
|
||||||
|
|
||||||
export default function ProtectedPage() {
|
|
||||||
const [session, loading] = useSession();
|
|
||||||
const router = useRouter();
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (!loading && !session) {
|
|
||||||
router.push('/auth/signin');
|
|
||||||
}
|
|
||||||
}, [loading, session, router]);
|
|
||||||
|
|
||||||
if (loading || !session) {
|
|
||||||
return <p>Loading...</p>;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div>
|
|
||||||
<h1>Protected Page</h1>
|
|
||||||
<p>Welcome, {session.user.email}</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
export async function getServerSideProps(context) {
|
|
||||||
const session = await getSession(context);
|
|
||||||
|
|
||||||
if (!session) {
|
|
||||||
return {
|
|
||||||
redirect: {
|
|
||||||
destination: '/auth/signin',
|
|
||||||
permanent: false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
props: { session }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user