I have made simple dynamic website and now I am struggling quite a while with logging in as an admin. As user no problems. After successful log in, token and role are checked (successfully) and then after redirect, I get unauthorized response. I am using mongodb, express and node.js. Thanks in advance for any suggestions.
Login.js: document.addEventListener("DOMContentLoaded", () => {
const userForm = document.getElementById("userForm");
const emailInput = document.getElementById("email");
const passwordInput = document.getElementById("password");
const errorMessage = document.getElementById("errorMessage");
const successMessage = document.getElementById("successMessage");
const apiUrl = "http://localhost:3000/login";
const handleFormSubmission = async (e) => {
e.preventDefault();
const loginUser = {
email: emailInput.value,
password: passwordInput.value,
};
try {
console.log("Sending login request:", loginUser);
const response = await fetch(apiUrl, {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify(loginUser),
});
console.log("Response status:", response.status);
const data = await response.json();
console.log("Response data:", data);
if (response.ok) {
successMessage.style.display = "block";
setTimeout(() => {
successMessage.style.display = "none";
}, 3000);
const { token, role } = data;
localStorage.setItem("token", token);
localStorage.setItem("role", role); // Store role as well
console.log(`TokenInLoginJS: ${token}, Role: ${role}`);
if (role === "admin") {
setTimeout(() => {
accessProtectedRoute("/admin", "admin");
}, 1000); // Added delay to ensure token storage
} else if (role === "user") {
window.location.href = "/";
} else {
showError("Unknown role. Please try again.");
}
} else {
showError(data.error || "Failed to log in");
}
} catch (error) {
console.error("Error during login request:", error);
showError("An error occurred while logging in. Please try again.");
}
};
userForm.addEventListener("submit", handleFormSubmission);
const showError = (message) => {
errorMessage.textContent = message;
errorMessage.style.display = "block";
setTimeout(() => {
errorMessage.style.display = "none";
}, 5000);
};
const accessProtectedRoute = async (endpoint, role) => {
const token = localStorage.getItem("token");
console.log(`Retrieved token AccessProtectedRoute: ${token}`);
if (!token) {
showError("No token found. Please log in again.");
return;
}
try {
const response = await fetch(endpoint, {
method: "GET",
headers: {
Authorization: `Bearer ${token}`,
},
});
if (response.ok) {
console.log(`Redirecting to ${role} page...`);
window.location.href = `/${role}`;
} else {
const data = await response.json();
showError(data.error || "Unauthorized access");
console.error(`Unauthorized access to ${endpoint}:`, data);
window.location.href = "/login";
}
} catch (error) {
showError("An error occurred. Please try again.");
console.error("Error accessing protected route:", error);
}
};
});
Admin.js: const token = localStorage.getItem("token");
console.log("Token in admin.js:", token);
if (!token) {
alert("No token found. Please log in again.");
window.location.href = "/login"; // Redirect to login if no token found
return;
}
// Function to include token in headers
const fetchWithAuth = async (url, options = {}) => {
const headers = {
"Content-Type": "application/json",
Authorization: `Bearer ${token}`,
...options.headers,
};
try {
const response = await fetch(url, { ...options, headers });
if (response.status === 401) {
alert("Unauthorized. Redirecting to login.");
window.location.href = "/login";
return null;
}
return response.json();
} catch (error) {
console.error(`Error fetching ${url}:`, error);
alert("An error occurred. Please try again.");
return null;
}
};
adminController.js: export const adminPage = (req, res) => {
try {
res.sendFile(path.join(__dirname, "/public/htmlCode/admin.html"));
} catch (error) {
console.error("Error sending admin page:", error);
res.status(500).json({ error: "Error sending admin page" });
}
};
controller.js: export const logInUser = async (req, res) => {
// Using try catch for catching errors while fetching
try {
// Extracting email and password from the document body
const { email, password } = req.body;
if (!email || !password) {
return res.status(400).json({ error: "Email and password are required" });
}
// Find User based on email
const user = await User.findOne({ email });
if (!user) {
return res.status(401).json({ error: "Invalid email or password" });
}
// Comparing match of password
const isMatch = await bcrypt.compare(password, user.password);
console.log("Password match result:", isMatch);
if (!isMatch) {
return res.status(401).json({ error: "Invalid email or password" });
}
// Token expiring in 1h
const token = jwt.sign(
{ id: user._id, email: user.email, role: user.role },
SECRET_KEY,
{
expiresIn: "1h",
}
);
res.status(200).json({ token, role: user.role });
// Catching errors
} catch (error) {
console.error("Error logging in user:", error);
res.status(500).json({ error: "Error logging in user" });
}
};
router.js: router.get("/admin", authenticateToken, isAdmin, adminPage);
New contributor
Pavol Ďuračka is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.