import React, { useState } from 'react';
import { useHistory } from 'react-router-dom';
import Cookies from 'js-cookie';
const LoginForm = () => {
const history = useHistory();
const [email, setEmail] = useState('');
const [password, setPassword] = useState('');
const handleLogin = (e) => {
e.preventDefault();
// Form validation goes here
// Perform login request
fetch('http://localhost:3001/api/student-login', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
email,
password,
}),
})
.then((response) => response.json())
.then((body) => {
if (body.success) {
// Successful login. Store the token as a cookie
Cookies.set('authToken', body.token, {
path: "localhost:3001/",
expires: 1,
sameSite:false
}); // Expiry set to 1 day
// Redirect to student page
history.push('/student');
} else {
alert('Log in failed');
}
});
};
return (
<>
<h1>Log In</h1>
<form id="log-in" onSubmit={handleLogin}>
<input
type="email"
placeholder="Email"
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<input
type="password"
placeholder="Password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<button type="submit">Log In</button>
</form>
</>
);
};
export default LoginForm;
This is my LoginForm, basically, when user logs in, if all credentials are correct, server side code will create a token. And in here, I store it into cookies, which is then sent to checkIfLoggedInStudent called in StudentPage to check the cookies, get the token stored in it and check if user exists.
MY PROBLEM: basically, when I use credentials="include" the error shows, but when I use credentials="same-origin" the error doesn't show however, isLoggedIn still remains to be equal to false, when supposedly if the cookies was passed correctly, isLoggedIn should equal to true and console.log('req.cookies:', req.cookies); in the function checkIfLoggedInStudent from the controller.js should output the cookies
import React, { useEffect } from 'react';
import { useHistory } from 'react-router-dom';
import Cookies from 'js-cookie';
const StudentPage = () => {
const history = useHistory();
useEffect(() => {
// Check if user is logged in
const authToken = Cookies.get('authToken');
console.log('Token exists:', authToken);
if (!authToken) {
// User is not logged in, redirect to login page
history.push('/login');
console.log('Token DOES NOT exists:', authToken);
} else {
// User is logged in, perform additional checks if needed
fetch('http://localhost:3001/api/checkIfLoggedInStudent', {
method: "POST",
mode: "cors",
credentials: "include",
headers: {
"Content-Type": "application/json"
},
})
.then((response) => response.json())
.then((body) => {
if (!body.isLoggedIn) {
// User is not logged in, redirect to login page
history.push('/login');
}
})
.catch((error) => {
console.log('Error:', error);
// Handle error as needed
});
}
}, [history]);
return (
<div>
<h1>Welcome to the Student Page</h1>
{/* Add your student page content here */}
</div>
);
};
export default StudentPage;
here's a snippet from my controller.js file
const studentLogin = async (req, res) => {
const email = req.body.email.trim();
const password = req.body.password;
// Check if email exists
const user = await Student.findOne({ email })
// Scenario 1: FAIL - User doesn't exist
if (!user) {
console.log("email does not exist");
return res.send({ success: false })
}
// Check if password is correct using the Schema method defined in User Schema
user.comparePassword(password, (err, isMatch) => {
if (err || !isMatch) {
// Scenario 2: FAIL - Wrong password
console.log("password are not match");
return res.send({ success: false });
}
// Scenario 3: SUCCESS - time to create a token
const tokenPayload = {
_id: user._id
}
const token = jwt.sign(tokenPayload, "LOGGED_IN_AS_STUDENT");
console.log("Generated token:", token);
// return the token to the client
return res.send({ success: true, token, username: user.name });
});
};
const checkIfLoggedInStudent = async (req, res) => {
console.log('req.cookies:', req.cookies);
if (!req.cookies || !req.cookies.authToken) {
// FAIL Scenario 1 - No cookies / no authToken cookie sent
console.log("no cookies");
return res.send({ isLoggedIn: false });
}
try {
// try to verify the token
const tokenPayload = jwt.verify(req.cookies.authToken, 'LOGGED_IN_AS_STUDENT');
// check if the _id in the payload is an existing user id
const student = await Student.findById(tokenPayload._id)
if (student) {
// SUCCESS Scenario - User is found
return res.send({ isLoggedIn: true })
} else {
// FAIL Scenario 2 - Token is valid but user id not found
return res.send({ isLoggedIn: false })
}
} catch {
// FAIL Scenario 3 - Error in validating token / Token is not valid
return res.send({ isLoggedIn: false });
}
}
here's also my router.js and index.s from the api folder (controller.js is also included in the folder):
updated router.js:
import express from 'express';
import cors from 'cors';
import {
getStudents,
getPendingStudents,
getAdmin,
getClearanceOfficer,
studentSignUp,
studentLogin,
elevatedUserLogin,
getAllApplications,
addApplicationToStudent,
getStudentApplications,
checkIfLoggedInStudent,
checkIfLoggedInElevated,
getLoggedInStudent,
approverSignUp
} from './apiController.js';
const app = express();
// Allow Cross Origin Resource Sharing
app.use(cors({ credentials: true, origin: 'http://localhost:3000' }));
app.get("/get-students", getStudents);
app.get("/get-pending-students", getPendingStudents);
app.get("/get-admin", getAdmin);
app.get("/get-clearance-officer", getClearanceOfficer);
app.get("/get-student-applications", getStudentApplications);
app.get("/get-all-applications", getAllApplications);
app.post("/student-signup", studentSignUp);
app.post("/approver-signup", approverSignUp);
app.post("/student-login", studentLogin);
app.post("/elevated-login", elevatedUserLogin);
app.post("/getLoggedInStudent", getLoggedInStudent);
app.post("/checkIfLoggedInStudent", checkIfLoggedInStudent);
app.post("/checkIfLoggedInElevated", checkIfLoggedInElevated);
app.post("/add-application", addApplicationToStudent);
export default app;
index.js:
import express from 'express';
import mongoose from 'mongoose';
import apiRouter from './apiRouter.js';
import fs from 'fs';
import { Approver, BuiltIn, Student } from './apiController.js';
const app = express();
const PORT = 3001;
// Connect to MongoDB
mongoose.connect('mongodb://127.0.0.1:27017/ClearanceApprovalSystem')
.then(async () => {
console.log('Connected to MongoDB');
// Import sample students data
const sampleStudentsData = fs.readFileSync('./samplestudents.json');
const students = JSON.parse(sampleStudentsData);
students.forEach(async (student) => {
const newStudent = new Student(student);
await newStudent.save();
});
console.log('Sample students imported to the collection.');
// Import sample builtin data
const sampleBuiltinData = fs.readFileSync('./samplebuiltin.json');
const builtins = JSON.parse(sampleBuiltinData);
builtins.forEach(async (builtin) => {
const newBuiltin = new BuiltIn(builtin);
await newBuiltin.save();
});
console.log('Sample built-in data imported to the collection.');
// Import sample builtin data
const sampleApproverData = fs.readFileSync('./sampleapprovers.json');
const approvers = JSON.parse(sampleApproverData);
approvers.forEach(async (approver) => {
const newApprover = new Approver(approver);
await newApprover.save();
});
console.log('Sample approver data imported to the collection.');
})
.catch((error) => {
console.error('Failed to connect to MongoDB:', error);
});
// Middleware
app.use(express.json());
app.use(express.urlencoded({ extended: false }));
// API routes
app.use('/api', apiRouter);
// Start the server
app.listen(PORT, () => {
console.log(`Server is running on port ${PORT}`);
});
Please help! I don't know what to do. This is the error I'm getting from the console:
Error: TypeError: Failed to fetch
at StudentPage.js:19:1
at commitHookEffectListMount (react-dom.development.js:23150:1)
at commitPassiveMountOnFiber (react-dom.development.js:24926:1)
at commitPassiveMountEffects_complete (react-dom.development.js:24891:1)
at commitPassiveMountEffects_begin (react-dom.development.js:24878:1)
at commitPassiveMountEffects (react-dom.development.js:24866:1)
at flushPassiveEffectsImpl (react-dom.development.js:27039:1)
at flushPassiveEffects (react-dom.development.js:26984:1)
at react-dom.development.js:26769:1
at workLoop (scheduler.development.js:266:1)
Also, I checked Network tab in the Developer Tools and it say CORS error
I added this console.log to the checkIfLoggedInStudent req.cookies: undefined no cookies